在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. 我可以从wsdl调用方法吗?
- 2. 我们可以在空对象上调用任何方法吗?
- 3. 我可以从Universal JS App(.NET)调用任何C#方法吗?
- 4. 我可以信任执行计划吗?
- 5. 我可以在Android的getView()方法中调用setContentView()方法吗?
- 6. MATLAB OOP,我可以调用调用类的方法吗?
- 7. PHP:我可以在我的课程内部调用我的方法吗?
- 8. 登录安全:我可以信任php的$ _SERVER ['REMOTE_ADDR']吗?
- 9. @compatibility_alias可以调用实例方法吗?
- 10. __destruct可见性为PHP
- 11. 我可以调用doGet方法并从servlet中检索信息吗?
- 12. 我们可以调用rake任务中的控制器方法吗?
- 13. Java - 我可以在远程对象中调用任意数量的方法吗?
- 14. 我可以写通用扩展方法来运行任务吗?
- 15. 我们可以用Struts2中的参数调用方法吗?
- 16. 我可以用变量调用方法吗?
- 17. 我可以使用私人方法吗?
- 18. 我可以将MongoDB集合信任为任务队列吗?
- 19. 我可以在PHP中使用两种构造方法吗?
- 20. 我可以指定从哪个类调用虚拟方法吗?
- 21. 我们可以通过js调用java方法吗?
- 22. 我可以通过ExternalInterface.call()方法调用匿名函数吗?
- 23. 我可以从AngularJS调用Django Manager方法吗?
- 24. 我可以让一个方法调用者返回吗?
- 25. 我可以在API级别19中调用Bundle#putString方法吗?
- 26. from/where我可以在类中调用静态类方法吗?
- 27. 我可以通过名称调用类的静态方法吗?
- 28. 我可以在Ruby测试中伪造调用方法吗?
- 29. 我可以从UIResponderStandardEditActions调用select方法吗?
- 30. 我可以通过数组调用一个方法吗?
我可以说,在关断过程中的异常可能会导致段故障。 – KingCrunch 2011-12-30 23:16:59
另外,在已经在exit()序列中的析构函数内部调用exit()可以终止进程,而无需调用额外的析构函数。 – 2013-05-29 15:17:57
对不起,我无法想象你的榜样。你可以详细说明吗? @JasonCohen – revo 2016-06-18 11:01:58