若想連裡面的物件也複製,可以設定 __clone方法,__clone 方法在複製新物件時會執行,所以可以設定複製時,要額外執行什麼動作。
範例 1:沒設定 __clone 方法,不會複製物件裡面的物件
class X1{ public $v1 = 0; } class X2{ public $v2 = 0; public $obj1; public function __construct() { $this->obj1 = new X1(); // 物件裡的物件 } } $a = new X2(); $b = clone $a; $b->v2 = 11; // 不會修改到 $a->v2 $b->obj1->v1 = 22; // $a->obj1->v1 也一起改變了 var_dump($a); var_dump($b);結果 $a->v2、$b->v2 分別為 0、11,表示 $a、$b 是不同物件。
但 $a->obj1->v1、$b->obj1->v1 都變成 22,
表示 $a->obj1 和 $b->obj1 還是指向同一個物件,因為 clone 是淺複製。
object(X2)#1 (2) { ["v2"]=> int(0) ["obj1"]=> object(X1)#2 (1) { ["v1"]=> int(22) } } object(X2)#3 (2) { ["v2"]=> int(11) ["obj1"]=> object(X1)#2 (1) { ["v1"]=> int(22) } }
範例 2:設定 __clone 方法,在 __clone ,再複製一次包含的物件。
class X1{ public $v1 = 0; } class X2{ public $v2 = 0; public $obj1; public function __construct() { $this->obj1 = new X1(); // 物件裡的物件 } //當 clone 發生時會執行 public function __clone(){ $this->obj1 = clone $this->obj1; } } $a = new X2(); $b = clone $a; $b->v2 = 11; // 不會修改到 $a->v2 $b->obj1->v1 = 22; // 不會修改到 $a->obj1->v1 var_dump($a); var_dump($b);結果 $a->obj1->v1、$b->obj1->v1 分別為 0、22,表示 $a->obj1 和 $b->obj1 是不同物件。
object(X2)#1 (2) { ["v2"]=> int(0) ["obj1"]=> object(X1)#2 (1) { ["v1"]=> int(0) } } object(X2)#3 (2) { ["v2"]=> int(11) ["obj1"]=> object(X1)#4 (1) { ["v1"]=> int(22) } }
參考:
http://php.net/manual/en/language.oop5.cloning.php
沒有留言:
張貼留言