php引用复制,浅复制clone和深复制

1.引用复制

<?php 
class  a {
    public $info=0;
}
$a=new a();
$b=$a;  //引用赋值
$a->info="10";
echo $a->info."<br>";
echo $b->info."<br>";
die; 

结果如下:

 

2.浅复制clone

<?php 
class  a {
    public $info=0;
}
$a=new a();
$b=clone $a;  //clone
$a->info="10";
echo $a->info."<br>";
echo $b->info."<br>";
die;

  结果如下

 

那么为什么叫浅复制呢,因为它只能复制类里面的属性和方法,如果类里面的属性和方法用到的其他的对象,那么复制过去的也是引用复制,如下:

<?php 
class mybianliang {
    public $bianliagn=0;
    public function __construct($bianliang){
        $this->bianliang=$bianliang;
    }
    public function changebianliang($bianliang2){
        $this->bianliang=$bianliang2;
    }
}
class  mytest {
    public $test=0;
    public function __construct($bianliang){
        $this->test=new mybianliang($bianliang);
    }
}
$a=new mytest(10);
$b= clone $a;   //clone
echo $a->test->bianliang."<br>";  
$a->test->changebianliang(20);       //改变a对象中test对象中的属性值,看看b对象中的test对象中的属性可有变化
echo $b->test->bianliang."<br>";
die;

  结果如下:

 这说明 $b对象中的$test对象指向的是$a对象的$test对象,那么如何避免呢

用__clone魔术方法把类中用的其他对象重新clone一下

<?php 
class mybianliang {
    public $bianliagn=0;
    public function __construct($bianliang){
        $this->bianliang=$bianliang;
    }
    public function changebianliang($bianliang2){
        $this->bianliang=$bianliang2;
    }
}
class  mytest {
    public $test=0;
    public function __construct($bianliang){
        $this->test=new mybianliang($bianliang);
    }    
    public function __clone(){
        $this->test=clone $this->test;   //克隆一下这个对象,不然指向的还是同一个对象
    } 
}
$a=new mytest(10);
$b= clone $a;   //clone
echo $a->test->bianliang."<br>";  
$a->test->changebianliang(20);       //改变a对象中test对象中的属性值,看看b对象中的test对象可有变化
echo $b->test->bianliang."<br>";
die;

结果如下

 3.深复制

   深复制,可以利用上面的魔术方法__clone()或者利用序列化和反序列化的方法

<?php 
class mybianliang {
    public $bianliagn=0;
    public function __construct($bianliang){
        $this->bianliang=$bianliang;
    }
    public function changebianliang($bianliang2){
        $this->bianliang=$bianliang2;
    }
}
class  mytest {
    public $test=0;
    public function __construct($bianliang){
        $this->test=new mybianliang($bianliang);
    }

}

$a=new mytest(10);
$b = unserialize(serialize($a));   //序列化和反序列化
echo $a->test->bianliang."<br>";  
$a->test->changebianliang(20);       //改变a对象中test对象中的属性值,看看b对象中的test对象可有变化
echo $b->test->bianliang."<br>";
die;

  执行结果

原文地址:https://www.cnblogs.com/flyyu/p/14119974.html