什么时候(在哪一刻)调用__destruct?

时间:2014-05-11 17:32:24

标签: php garbage-collection reference-counting

在考虑没有参考周期的简单对象时,是否有一些保证调用__destruct时?我从java中知道,当调用函数finalize时它没有被定义,它取决于垃圾收集器。

例如,如果您有以下功能:

1   function test(){
2       $x = new SomeObject();
3       $y = new SomeObject();
4       $x = null;
5   }

SomeObject没有参考周期。

您能否认为第4行调用$x->__destruct而第5行调用$y->__destruct

测试以下脚本似乎表明这是真的: https://gist.github.com/KAYLukas/0b1d65e57b52862f8da5

此外,SplFileObject似乎适用于此谓词:无法关闭文件,而只需将变量设置为null即可。如果这不能直接调用__destruct,则在使用SplFileObject打开文件后无法打开文件。

我发现可以确保最终会调用__destruct,而不是在何时调用。

1 个答案:

答案 0 :(得分:1)

是的,你可以认为。

__destruct总是在对象的最后一次引用消失时被调用:当你无法以任何方式从外部访问该对象时。

如果存在循环引用,则需要等到循环垃圾收集器进入,其中没有定义它发生的位置。

如果您已将对象存储在其他位置,则需要先在调用析构函数之前将其从中删除。

有关详细信息:内部对象并不总是在__destruct上破坏其资源(因为用户可能直接调用它),但仅限于对象确实被销毁时。 (防止段错的技术措施)

同样在关机期间,第一个变量和数组将按照它们被定义的反向顺序被移除,并且对象的最后一个引用消失,对象被销毁。然后循环垃圾收集器进入并删除其他对象并在那里调用__destruct

这里唯一未定义的是循环垃圾收集器删除对象并调用其__destruct函数的顺序。