zoukankan      html  css  js  c++  java
  • 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操作就是浅复制,序列化反序列化就是深复制

  • 相关阅读:
    blocksit
    getdata
    ASP.net 探针
    301重定向
    webapi
    Unity NGUI UIPanel下对粒子的剪裁
    unity3d 之本地推送
    c#之时间戳与DateTime的相互转换
    c#之从服务器下载压缩包,并解压
    Unity3d 开发之 ulua 坑的总结
  • 原文地址:https://www.cnblogs.com/orlion/p/5350835.html
Copyright © 2011-2022 走看看