在我的__clone
方法中,我通过引用将一个变量分配给另一个变量。克隆之后,我期望发生的是,当我为一个对象更改此变量时,它会在另一个对象中更改。但这似乎并没有发生。
我的代码:
class a {
var $a;
function a($var = NULL) {
if (isset($var)) {
$this->a = $var;
}
}
function __clone() {
$temp = new a();
$temp->a = &$this->a;
return $temp;
}
}
$a = new a('test');
$b = clone $a;
$b->a = 'zzz';
echo $a->a;
echo "\r\n";
echo $b->a;
输出是这样的:
test
zzz
我希望它是这样的:
zzz
zzz
答案 0 :(得分:1)
如果我在克隆时没有弄错,那么引用就会被删除(我认为这是一种内部机制),它会使你想要实现的内容混淆,因为你可以这样做:
$a = new a('test');
$b = $a;
$b->a = 'zzz';
echo $a->a;
echo "\r\n";
echo $b->a;
引用:“...您要创建此其他对象的新实例,以便副本具有自己的单独副本。”
答案 1 :(得分:1)
那是因为__clone()
的返回值被忽略了。您可以看到,如果您将$temp->a = &$this->a;
行更改为$temp->a = 'CLONED';
,然后只需echo $b->a;
因此,您无法更改克隆的结果对象。
答案 2 :(得分:1)
在调用__clone
方法之前,PHP已经按值复制了所有属性。 PHP完成克隆对象后,将调用您的方法。因此,您在该方法中访问的任何属性都是值副本。文档说明:
克隆对象时,PHP 5将执行所有对象属性的浅表副本。任何引用其他变量的属性都将保留引用。
克隆完成后,如果定义了__clone()方法,则将调用新创建的对象的__clone()方法,以允许任何需要更改的必要属性。
您可以在this page的第二段找到此信息。
虽然这不是一个非常漂亮的解决方法,但您可以重命名__clone
方法。然后,您可以使用该方法克隆您的对象,虽然这当然不再是实际的克隆,因为它不使用接口进行克隆。