PHP浅复制与深复制

初稿链接:http://www.orlion.ga/731/

php用clone复制对象来一个题目,下面用代码来证明问题:

class Foo{

    public $bar;

    public $name;

    public function __construct(Bar $bar , $name){
        $this->bar = $bar;
        $this->name = $name;
    }
}

class Bar{

    public $name;

    public function __construct($name){
        $this->name = $name;
    }
}

$bar = new Bar('bar obj');
$foo = new Foo($bar , 'foo obj');

$cloneFoo = clone $foo;
$cloneFoo->name = 'clone foo obj';
$cloneFoo->bar->name = 'new bar obj';

var_dump($foo->name);
var_dump($foo->bar->name);

var_dump($cloneFoo->name);
var_dump($cloneFoo->bar->name);

输出是:

string 'foo obj' (length=7)
string 'new bar obj' (length=11)
string 'clone foo obj' (length=13)
string 'new bar obj' (length=11)

    输出说明了一个问题:$cloneFoo->bar->name = ‘new bar
obj’;这句话本意是想念将$cloneFoo中之$bar的name修改了。但是也顺手着把$foo的$bar的name也被改了。也就是说$foo和$cloneFoo中之bar是和一个bar。这说明万一目标
Foo 中保存在对象 Bar 的援,当您复制对象
Foo时,php并无见面克隆一个Bar对象吃后帮忙您拿这个克隆出来的Bar给您作及克隆出来的cloneFoo中

        那么什么样解决是题材为,可以运用php的序列化

$bar = new Bar('bar obj');
$foo = new Foo($bar , 'foo obj');

$cloneFoo = unserialize(serialize($foo));
$cloneFoo->name = 'clone foo obj';
$cloneFoo->bar->name = 'new bar obj';

var_dump($foo->name);
var_dump($foo->bar->name);

var_dump($cloneFoo->name);
var_dump($cloneFoo->bar->name);

    输出:

string 'foo obj' (length=7)
string 'bar obj' (length=7)
string 'clone foo obj' (length=13)
string 'new bar obj' (length=11)

    序列化是一个递归的长河,我们无待理会被对象中引用了多少只目标同引用了小层对象,我们都好彻底底复制。

 

    clone操作就是浅复制,序列化反序列化就是深复制

相关文章