在php中,对象间的赋值操作时间上是引用操作。比如
class myclass
{
public $data;
}
$obj1 = new myclass();
$obj1->data = 1;
$obj2 = $obj1;
$obj2->data = 2;
print_r($obj1->data); //输出2
print_r($obj2->data); //输出2
但是如果你不直接引用,而是使用clone,就相当于制作了一个独立的副本对象
$obj2 = clone $obj1;
$obj2->data = 2; //此时对obj2对象所做的修改就和obj1对象毫无关系了
但是,此时obj1和obj2也并不是完全分离开了,看第二个例子
class itemObject
{
public $count = 0;
public function add()
{
$this->count = ++$this->count;
}
}
$item = new itemObject();
$obj1->item = $item;
print_r($item); //Object ( [count] => 0 )
print_r($obj1); //Object ( [data] => 1 [item] => Object ( [count] => 0 ) )
$obj2 = clone $obj1;
$obj2->data = 2;
$obj2->item->add();
print_r($item); // Object ( [count] => 1 )
print_r($obj1); //Object ( [data] => 1 [item] => Object ( [count] => 1 ) )
print_r($obj2); //Object ( [data] => 2 [item] => Object ( [count] => 1 ) )
通过上面的例子可以看到,我们在obj2中改变了一个引用对象的属性,导致所有引用这个对象的对象,包括这个对象自己的属性都被改变了。
这就是所谓的浅复制。
而深复制,就是原形和复制对象完全分离开来。他的实现非常简单,只要我们在被复制对象中增加一个clone魔术方法即可。被复制对象一旦被复制的时候,就放弃自己的属性,把属性给要求复制的对象,然后自己存一个属性的副本;这样我们复制这个对象的时候,后续对象就不会因为引用的关系而改变源对象了。
class myclass
{
public $data;
public $item;
public function __clone()
{
$this->item = clone $this->itme;
}
}