php用clone复制对象有一个问题,下面用代码来说明问题:
classFoo{ public$bar; public$name; publicfunction__construct(Bar$bar,$name){ $this->bar=$bar; $this->name=$name; } } classBar{ public$name; publicfunction__construct($name){ $this->name=$name; } } $bar=newBar('barobj'); $foo=newFoo($bar,'fooobj'); $cloneFoo=clone$foo; $cloneFoo->name='clonefooobj'; $cloneFoo->bar->name='newbarobj'; var_dump($foo->name); var_dump($foo->bar->name); var_dump($cloneFoo->name); var_dump($cloneFoo->bar->name);
输出是:
string'fooobj'(length=7) string'newbarobj'(length=11) string'clonefooobj'(length=13) string'newbarobj'(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=newBar('barobj'); $foo=newFoo($bar,'fooobj'); $cloneFoo=unserialize(serialize($foo)); $cloneFoo->name='clonefooobj'; $cloneFoo->bar->name='newbarobj'; var_dump($foo->name); var_dump($foo->bar->name); var_dump($cloneFoo->name); var_dump($cloneFoo->bar->name);
输出:
string'fooobj'(length=7) string'barobj'(length=7) string'clonefooobj'(length=13) string'newbarobj'(length=11)
序列化是一个递归的过程,我们不需要理会被对象内部引用了多少个对象以及引用了多少层对象,我们都可以彻底的复制。
clone操作就是浅复制,序列化反序列化就是深复制。
关于“PHP浅复制与深复制是什么,怎样说明”就介绍到这了,如果大家觉得不错可以参考了解看看,如果想要了解更多,欢迎关注恒创科技,小编每天都会为大家更新不同的知识。