2014-12-02 76 views
1

我想摧毀一個對象和實習對象。爲什麼下面的例子不工作:摧毀主要對象時銷燬嵌入對象

<?php 
class I 
{ 
    public $elt = 'hello world!!'; 
    public function __destruct() 
    { 
     var_dump('I: destroyed'); 
    } 
} 

class A 
{ 
    public $val1=1; 
    public $val2=2; 
    public $val3=3; 
    public $val4=4; 
    public $i; 
    public function __construct($i) 
    { 
     $this->i = $i; 
    } 
    public function __destruct() 
    { 
     var_dump('A destroyed'); 
     unset($this->i); 
    } 
} 

$i = new I(); 
$a = new A($i); 
unset($a); 
var_dump($i); 

OUTPUT:

string(11) "A destroyed" 
    object(I)#1 (1) { ["elt"]=> string(13) "hello world!!" } 
    string(12) "I: destroyed" 

爲什麼我沒有得到通知Undefined variable: i? 在$ i的var_dump之後,如何顯示類I的析構函數的消息?

UPDATE

的事情是,我有一個主對象,這個對象有吹掃/在循環的每次迭代結束刷新其嵌套的對象。

+0

請注意,刪除嵌套對象並不是必需的。在腳本結尾處,對象將被自動刪除。 – 2014-12-02 11:05:54

+0

其實我必須這樣做,因爲我的主要對象是在一個循環內部使用的,而且我需要清除所有嵌套的對象 – smarber 2014-12-02 11:08:48

+0

而且在清除嵌套對象之後是否還想使用主對象? – 2014-12-02 11:11:12

回答

2

講起了四行代碼:

$i = new I(); 
$a = new A($i); 
unset($a); 
var_dump($i); 

第一行創建I類型的對象和變量$i存儲對它的引用(PHP對象總是被指定爲參考,則需要使用運營商clone創建副本)。

第二行將$i傳遞給A類的構造函數,並創建對存儲在$a->$i中的同一對象的另一個引用。

第三行破壞A類型的對象;這將刪除對I類型的對象的第二個引用,但它不會影響第一個;變量$i仍然持有它。

第四行轉儲永遠不會未設置的變量$i的內容。它是在第一行創建的I類型的對象。

如果要銷燬類型爲I的對象,並且銷燬類型爲A的對象時,請確保沒有其他引用。這可以通過在A類的構造函數中創建類型爲I的對象或在將其傳遞給類A的構造函數後,將所有對$i的引用刪除來完成。在$a = new A($i);之後添加unset($i);就可以完成這項工作。

+0

聽起來很完美。所以你建議我保留A類的析構函數。 – smarber 2014-12-02 11:17:00

+1

你並不需要類A的析構函數。有或沒有它時,當'A'類型的對象被破壞時,它們對'I'類型對象的引用無論如何都被移除。在這種情況下保留或刪除它只是個人喜好的問題。您可以保留它們以進行調試,並在確定對象被銷燬並且不遲於此時銷燬它們時將其移除。 – axiac 2014-12-02 11:40:46

1

從PHP文件:http://php.net/manual/en/language.oop5.decon.php

析構函數在腳本關閉時調用有HTTP標頭 已經發出。腳本關閉階段中的工作目錄 可能與某些SAPI(例如Apache)不同。

銷燬方法將在執行完其他調用後調用。意思是你的var_dump($ i)會先被調用,然後執行破壞。