PHP中的浅复制与深复制

在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;
    }
}


书山有路勤为径 学海无涯苦作舟