2013-10-26 70 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;

因此,您無法更改克隆的結果對象。