原文: 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的数据。