诸如 “$obj 1 = $obj 2” 之类 PHP 语句只是在内存中创建对同一对象的另一个引用。因此,属性的更改会同时反映在原始对象和复制对象中。PHP clone 关键字创建对象的浅表副本。
原始对象中的更改不会反映在浅层副本中。
例子
请看下面的例子 -
将产生以下输出 -
Hello World Hello World
在第一种情况下,$y 只是 $x 的引用副本。因此,var1 属性的任何更改都会反映在两者中。
但是,如果我们将 $y 声明为 $x 的克隆,则原始对象中的任何更改都不会反映在其浅表副本中。
例子
请看下面的例子 -
将产生以下输出 -
Hello PHP Hello World
例子
在下面的代码中,myclass 具有属性名称作为地址类的对象。myclass 的对象通过赋值进行复制。其嵌入地址对象值的任何更改都会反映在这两个对象中,但 name 属性的更改不会在克隆对象中受到影响。
将产生以下输出 -
myclass Object
(
[name] => Raja
[obj] => address Object
(
[city] => Nanded
[pin] => 431601
)
)
变更后: 原始对象
myclass Object
(
[name] => Ravi
[obj] => address Object
(
[city] => Mumbai
[pin] => 400001
)
)
复制对象
myclass Object
(
[name] => Ravi
[obj] => address Object
(
[city] => Mumbai
[pin] => 400001
)
)
使用 “clone” 关键字
在浅拷贝中,原始对象的任何引用其他变量的属性都将保持引用。clone 关键字不会复制复制的对象。
现在,我们创建 myclass 对象的克隆,以便 $obj 2 是 $obj 1 的克隆。我们将 $obj 1 的 name 属性从 Raja 更改为 Ravi,并修改嵌入的地址对象。属性更改不会反映在其克隆中,但引用的地址对象将发生更改。
例子
请看下面的例子 -
将产生以下输出 -
myclass Object
(
[name] => Raja
[obj] => address Object
(
[city] => Nanded
[pin] => 431601
)
)
更改后:原始对象
myclass Object
(
[name] => Ravi
[obj] => address Object
(
[city] => Mumbai
[pin] => 400001
)
)
复制对象
myclass Object
(
[name] => Raja
[obj] => address Object
(
[city] => Mumbai
[pin] => 400001
)
)
使用 __clone() 方法
clone 关键字创建对象的浅表副本。当一个对象被克隆时,PHP 将执行该对象所有属性的浅表复制。对其他变量的引用的任何属性都将保持引用。因此,对原始对象所做的任何更改也会显示在克隆的对象中。
如果你希望阻止复制的对象自动更新,我们需要使用 __clone() 方法创建对象的深层副本。它是 PHP 中的神奇方法之一。
克隆完成后,如果定义了 __clone() 方法,则将调用新创建的对象的 __clone() 方法,以允许需要更改的任何必要属性。
例子
在上面的例子中,我们有一个 myclass 的对象,它的一个属性 $obj 保存对 address 类对象的引用。为了实现深拷贝,我们覆盖了 myclass 中的 __clone() 魔术方法。
您现在将看到原始对象中的更改(我们更改了 address 属性)不会反映在克隆的对象中,如以下输出所示 -
myclass Object
(
[name] => Raja
[obj] => address Object
(
[city] => Nanded
[pin] => 431601
)
)
更改后:原始对象
myclass Object
(
[name] => Ravi
[obj] => address Object
(
[city] => Mumbai
[pin] => 400001
)
)
克隆对象
myclass Object
(
[name] => Raja
[obj] => address Object
(
[city] => Nanded
[pin] => 431601
)
)