2013-10-26 47 views
-1

在我的__clone方法中,我通过引用将一个变量分配给另一个变量。克隆之后我期望发生的事情是,当我为一个对象更改此变量时,它将在另一个对象中发生变化。但这似乎并没有发生。在__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 

回答

1

在调用__clone方法之前,PHP已经按值复制了所有属性。在PHP完成克隆你的对象后,你的方法被调用。因此,您在该方法中访问的任何属性都是值副本。该文档指出:

当一个对象被克隆时,PHP 5将执行所有对象属性的浅表副本。任何引用其他变量的属性都将保留引用。

克隆完成后,如果定义了__clone()方法,则将调用新创建的对象的__clone()方法,以允许任何需要更改的必要属性。

您可以在this page的第二段找到它。

尽管这不是一个非常漂亮的解决方法,但您可以重命名__clone方法。然后,您可以使用该方法来克隆您的对象,但这当然不再是实际的克隆,因为它不使用该接口进行克隆。

1

如果我克隆时没弄错该参考被删除(我认为这是一个内部机制),它混淆了你想实现的目标,因为你可以简单地这样做:

$a = new a('test'); 
$b = $a; 
$b->a = 'zzz'; 

echo $a->a; 
echo "\r\n"; 
echo $b->a; 

报价:“......你想要创建这个其他对象的新实例,这样副本都有自己单独的副本。”

来源:http://php.net/manual/ro/language.oop5.cloning.php

1

这是因为__clone()返回值被忽略。您可以看到,如果将$temp->a = &$this->a;行更改为$temp->a = 'CLONED';,然后只需更改echo $b->a;

因此,您无法更改克隆的结果对象。