我可以信任PHP __destruct()方法被调用?(Can I trust PHP __dest

2019-07-20 19:35发布

在PHP5,是__destruct保证被调用用于每个对象实例()方法? 在程序异常可以防止这种情况发生?

Answer 1:

当所有的引用都被释放的析构函数被调用,或当脚本终止。 我认为,这意味着当脚本终止正常。 我要说的是,关键的例外也不能保证被调用析构函数。

该PHP文件是有点薄,但它说,在析构函数中的异常会导致一些问题。



Answer 2:

另外值得一提的是,有它自己的析构函数一个子类的情况下,父析构函数不会自动被调用。

你必须明确地调用父:: __自毁()从子类__destruct()方法,如果父类做任何必要的清理。



Answer 3:

根据我的经验析构函数将总是叫在PHP 5.3,但被警告,如果某些一段代码调用exit(),或者如果发生致命错误,PHP会调用析构函数中的“任何”命令(我认为实际的顺序是为了在存储器或存储被保留给对象的顺序。在实践中,这个顺序是几乎总是有问题的)。 这被称为PHP文档中的“关机序列”。

析构函数的PHP文件说:

PHP 5引入类似于其它面向对象的语言,例如C ++的析构函数的概念。 析构函数方法将被尽快有一个特定的对象的任何其它引用调用,或者在关断期间,任何顺序。

因为如果你有X类持有至Y的引用的结果,X的析构函数可以被调用后Y的析构函数已经被调用。 我们希望,参考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引擎命中段故障或其他一些内部错误发生,那么所有的赌注都关闭。

如果你想了解当前的实现“关闭序列”中,看到https://stackoverflow.com/a/14101767 。 注意,此实现可能在将来的PHP版本改变。



Answer 4:

有循环引用的当前错误,停止被称为隐式的销毁方法。 http://bugs.php.net/bug.php?id=33595应当固定在5.3



Answer 5:

如果你想要去肯定使用关机功能: register_shutdown_function()来



文章来源: Can I trust PHP __destruct() method to be called?