賦值 vs 克隆
<?php
$objA = new MyClass();
$objB = $objA; // 引用賦值,指向同一記憶體地址
$objC = clone $objA; // 克隆,創建新對象
?>
$objA = $objB:引用同一實例,修改任一屬性雙方同步變化
clone:創建獨立副本,屬性值複製,但引用型別屬性仍指向同一對象 (淺拷貝)
__clone() 魔術方法實現深拷貝
<?php
class SubClass {
private $name = 'fdipzone';
private $age = '30';
public function __clone() {
$this->name = 'xfdipzone';
$this->age = '29';
}
}
class MyClass {
public $p1;
public $p2;
public function __clone() {
$this->p1 = clone $this->p1; // 手動深拷貝引用屬性
// $this->p2 保持淺拷貝
}
}
$obj = new MyClass();
$obj->p1 = new SubClass();
$obj->p2 = new SubClass();
$obj2 = clone $obj;
/*
obj.p1 -> SubClass#2 (fdipzone, 30)
obj.p2 -> SubClass#3 (fdipzone, 30)
obj2.p1 -> SubClass#5 (xfdipzone, 29) // 深拷貝並觸發 __clone
obj2.p2 -> SubClass#3 (fdipzone, 30) // 淺拷貝,同一實例
*/
?>
最佳實踐
- 不可變對象 (Value Object) 無需克隆
- 含資源句柄、資料庫連線等不可共享資源時必須實現
__clone 深拷貝
- 大型對象圖克隆考慮序列化反序列化:
unserialize(serialize($obj)) (性能較差但徹底)
- PHP 7.4+ 可用
__clone 配合 readonly 屬性簡化邏輯