若想連裡面的物件也複製,可以設定 __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
沒有留言:
張貼留言