php对象的拷贝原理(附图解)

原文: https://blog.csdn.net/xyz_dream/article/details/64440278


php对象的拷贝有三种常用的方式: 先定义一个Dog类。


        class Dog{

public $name;

public $age;

}
$dog=new Dog();



1. $dog2=$dog; // 直接复制拷贝




2. $dog2=&$dog; //引用赋值拷贝




3. $dog2= clone $dog; //克隆拷贝




首先讲解第一种方式的原理:




先来看看下面一段测试代码:




$dog ->name=”大黄”;
$dog->age=2;

$dog2=$dog; //直接赋值

var_dump($dog,$dog2); //查看一下对象标识符


echo $dog2->name.’<br/>’;//此时还是输出 “大黄”

$dog->name=”小黑”;//注意 $dog改变名字了

echo $dog2->name.’<br/>’;// 此时输出$dog2的name变成了 “小黑”

此标标识符称为 对象标识符。大家可以看出 两者 $dog ,$dog2的对象标识符是一样的。





直接赋值的这种拷贝只是 拷贝了 对象标识符的一个副本而已,但是对象标识符的数据指向并没有改变,都是指向同一块数据块。 所以就有了$dog->name=”小黑”的时


候输出$dog2->name变成小黑的原因所在! 并且大家在var_dump();函数的帮助下也看到了,确实两者的对象标识符是一样的!




其次讲解第二种拷贝方式: 赋值引用


还是先看一下测试代码:



$dog = new Dog();

$dog ->name=”大黄”;
$dog->age=2;

$dog2=&$dog; // 引用赋值拷贝

var_dump($dog,$dog2); //查看一下对象标识符

$dog2=”abc”;

echo $dog->name.’<br/>’; //直接报错! 此时的$dog已经是字符串了 不再是对象

echo $dog2.’<br/>’;//输出 “abc”

输出的结果:





引用标识符都是一致的,但是$dog2改变了他们的共同指向,使对象标识符变成了字符串”abc”,那么此时此标识符不再是对象标识符,而是一个字符串,则echo $dog-


>name就会报错,echo $dog2就会输出 “abc”;





最后讲一下第三种拷贝方式: 使用 关键字 clone 进行拷贝




先看测试代码:




$dog = new Dog();

$dog ->name=”大黄”;
$dog->age=2;

$dog2=clone $dog; // 克隆拷贝

var_dump($dog,$dog2); //查看一下对象标识符

echo $dog->name.’<br/>’;

$dog->name=”小黑”;

echo $dog->name.’<br/>’;

echo $dog2->name.’<br/>’;

输出结果:



最明显的改变是:   两者的对象标识符是不同的,这就意味着指向的数据块也是不用的,此时输出$dog->name以及改变$dog->name都不会影响$dog2的数据。