2008-09-30 44 views

回答

35

當所有引用被釋放或腳本終止時,將調用析構函數。我認爲這意味着腳本正常終止。我會說重要的例外不能保證析構函數被調用。

PHP documentation是有點薄,但它確實說,析構函數中的異常會導致問題。

+1

我可以說,在關斷過程中的異常可能會導致段故障。 – KingCrunch 2011-12-30 23:16:59

+4

另外,在已經在exit()序列中的析構函數內部調用exit()可以終止進程,而無需調用額外的析構函數。 – 2013-05-29 15:17:57

+1

對不起,我無法想象你的榜樣。你可以詳細說明嗎? @JasonCohen – revo 2016-06-18 11:01:58

41

還值得一提的是,在具有自己的析構函數的子類的情況下,父析構函數是而不是自動調用。

你必須明確地調用父:: __自毀()從子類__destruct()方法,如果父類做任何必要的清理。

+14

我相信只有當子類實現自己的__destruct()時纔是真實的,否則將調用父__destruct()。 – Geoff 2008-09-30 04:03:26

11

以我的經驗析構函數將總是叫在PHP 5.3,但被警告,如果某些一段代碼調用exit(),或者如果發生致命錯誤,PHP會調用析構函數「任何「順序(我認爲實際的順序是內存中的順序或內存爲對象保留的順序,實際上,這個順序幾乎總是有問題的)。這在PHP文檔中被稱爲「關閉序列」。

PHP documentation of destructors說:

PHP 5引入類似於其它面向對象的語言,例如C++的析構函數的概念。只要沒有其他對特定對象的引用,或者在關閉序列中以任何順序,就會調用析構函數方法。

因此,如果您有擁有對Y的引用的類X,則可能會在Y的析構函數已被調用後調用X的析構函數。希望對Y的引用不是那麼重要......官方說這不是一個錯誤,因爲它已被記錄。

但是,解決此問題非常困難,因爲官方PHP沒有提供方法來知道析構函數是否正常調用(析構函數按正確順序調用)或析構函數以「任何」順序調用,您無法使用引用的數據因爲這些對象可能已經被破壞。可以使用debug_backtrace()和檢查堆棧來解決這種缺乏檢測問題。缺乏正常的堆棧似乎意味着PHP 5.3的「關閉序列」,但這也是未定義的。如果你有循環引用,這些對象的析構函數根本不會被PHP 5.2或更低版本調用,並且將在PHP 5.3或更高版本的「關閉序列」期間以「任意」順序調用。對於循環引用,不存在邏輯上「正確」的順序,所以「任何」順序對於那些順序都是好的。

也有一些例外(這是PHP畢竟):

  • 如果exit()被稱爲在另一個析構函數,任何剩餘的析構函數不會被調用(http://php.net/manual/en/language.oop5.decon.php
  • 如果任何地方發生FATAL錯誤(多可能的原因,例如試圖從任何其他析構函數中拋出異常可能是一個原因)

當然,如果PHP引擎命中分段錯誤或其他一些inter最後一個問題發生,那麼所有投注都關閉。

相關問題