2008-09-30 57 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最后一个问题发生,那么所有投注都关闭。

相关问题