在PHP5中,是否保證爲每個對象實例調用__destruct()方法?程序中的異常可以防止這種情況發生?我可以信任調用PHP __destruct()方法嗎?
回答
當所有引用被釋放或腳本終止時,將調用析構函數。我認爲這意味着腳本正常終止。我會說重要的例外不能保證析構函數被調用。
該PHP documentation是有點薄,但它確實說,析構函數中的異常會導致問題。
還值得一提的是,在具有自己的析構函數的子類的情況下,父析構函數是而不是自動調用。
你必須明確地調用父:: __自毀()從子類__destruct()方法,如果父類做任何必要的清理。
我相信只有當子類實現自己的__destruct()時纔是真實的,否則將調用父__destruct()。 – Geoff 2008-09-30 04:03:26
有一個循環引用的當前錯誤,可以停止隱式調用destruct方法。 http://bugs.php.net/bug.php?id=33595 應固定在5.3
以我的經驗析構函數將總是叫在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最後一個問題發生,那麼所有投注都關閉。
,如果你想要去確保使用關機功能:register_shutdown_function()
- 1. 可以使用php __destruct方法在這種情況下
- 2. 我可以從wsdl調用方法嗎?
- 3. 我們可以在空對象上調用任何方法嗎?
- 4. 我可以從Universal JS App(.NET)調用任何C#方法嗎?
- 5. 我可以用相同的方法調用一個方法嗎?
- 6. 我可以信任Java SecurityManager沙箱嗎?
- 7. 我可以信任執行計劃嗎?
- 8. 我可以在Android的getView()方法中調用setContentView()方法嗎?
- 9. 你可以信任mysql_insert_id嗎?
- 10. MATLAB OOP,我可以調用調用類的方法嗎?
- 11. PHP:我可以在我的課程內部調用我的方法嗎?
- 12. 登錄安全:我可以信任php的$ _SERVER ['REMOTE_ADDR']嗎?
- 13. 每次調用@RequestMapping方法後,我可以調用一個方法嗎?
- 14. @compatibility_alias可以調用實例方法嗎?
- 15. __destruct可見性爲PHP
- 16. 我可以調用doGet方法並從servlet中檢索信息嗎?
- 17. 我可以寫通用擴展方法來運行任務嗎?
- 18. 我們可以調用rake任務中的控制器方法嗎?
- 19. Java - 我可以在遠程對象中調用任意數量的方法嗎?
- 20. 我可以使用str2func調用一個類方法嗎?
- 21. 我可以用變量調用方法嗎?
- 22. 我們可以用Struts2中的參數調用方法嗎?
- 23. 我可以使用私人方法嗎?
- 24. 我可以將MongoDB集合信任爲任務隊列嗎?
- 25. PHP類和靜態變量 - 我應該使用__destruct()嗎?
- 26. 我應該在php __destruct()中使用unset嗎?
- 27. 我可以使用字符串方法名稱調用c#動態方法嗎?
- 28. 我可以從手錶調用方法並安裝嗎?
- 29. 我可以將CGContextRef傳遞給從drawRect調用的方法嗎?
- 30. 我可以從它的類方法調用析構函數嗎?
我可以說,在關斷過程中的異常可能會導致段故障。 – KingCrunch 2011-12-30 23:16:59
另外,在已經在exit()序列中的析構函數內部調用exit()可以終止進程,而無需調用額外的析構函數。 – 2013-05-29 15:17:57
對不起,我無法想象你的榜樣。你可以詳細說明嗎? @JasonCohen – revo 2016-06-18 11:01:58