在PHP__destruct和register_shutdown_function执行顺序
根据PHP手册的解析。__destruct是
当对对象的所有引用被删除或对象被显式销毁时,就会执行析构函数。
和register_shutdown_function是
在执行脚本完成或完成()之后执行的寄存器、A、回调函数注册一个回调函数。当脚本运行或调用到()时执行此函数。
从字面上看,__destruct是对象的水平,并register_shutdown_function是剧本整体水平。它应该是register_shutdown_function水平较高,其注册功能也应执行最后确认我们的猜测,我们写了一个剧本:
复制代码代码如下所示:
register_shutdown_function(function(){ echo'global;});
类{
公共功能__construct(){
}
公共功能__destruct()
{
回声__class__,'::',__function__,;
}
}
新的一个;
实施结果:
复制代码代码如下所示:
答::__destruct
全球的
完全证实了我们的怀疑,这是按照对象脚本的顺序执行的。
但如果我们注册register_shutdown_function的对象吗是相同的顺序吗!
复制代码代码如下所示:
类{
公共功能__construct(){
register_shutdown_function(function(){ echo'local '、';});
}
公共功能__destruct()
{
回声__class__,'::',__function__,;
}
}
新的一个;
结果uff1a
复制代码代码如下所示:
局部
答::__destruct
你可以看到,register_shutdown_function就是第一,最后就是执行对象的__destruct。这表明register_shutdown_function注册函数是在类的方法。它不知道,这可能需要一个视图的PHP源代码解析。
我们可以扩大视野:
复制代码代码如下所示:
register_shutdown_function(function(){ echo'global '、';});
类{
公共功能__construct(){
register_shutdown_function(阵列($,'op '));
}
公共功能__destruct()
{
回声__class__,'::',__function__,;
}
公共职能部门()
{
回声__class__,'::',__function__,;
}
}
B类{
公共功能__construct()
{
register_shutdown_function(阵列($,'op '));
$ obj =新一;
}
公共功能__destruct()
{
回声__class__,'::',__function__,;
}
公共职能部门()
{
回声__class__,'::',__function__,;
}
}
新的b;
我们登记了register_shutdown_function功能在全球范围内,我们登记在AB类,有一个分析的方法分别在上课。操作的最终结果是什么
复制代码代码如下所示:
全球的
B:OP
答:OP
答::__destruct
B::__destruct
结果完全颠覆了我们的想象。的register_shutdown_function函数是在类或在全球登记首先执行。班里的秩序是他们注册的顺序。如果我们仔细研究,register_shutdown_function全球功能在前面或后面的都是这个结果,事情似乎有了结果,__destruct实施之前,register_shutdown_function,的register_shutdown_function函数和全局注册类register_shutdown_function实施之前。
等一下,我不能接受这个结果,根据得出的结论,有人说,剧本也可以__destruct结束后执行!所以,我会继续验证这一结论,删除注册register_shutdown_function在课堂上,并保持全球register_shutdown_function:
复制代码代码如下所示:
类{
公共功能__destruct()
{
回声__class__,'::',__function__,;
}
}
B类{
公共功能__construct()
{
$ obj =新一;
}
公共功能__destruct()
{
回声__class__,'::',__function__,;
}
}
register_shutdown_function(function(){ echo'global '、';});
输出:
复制代码代码如下所示:
答::__destruct
全球的
B::__destruct
结果很令人困惑。对两类A和B的析构函数的执行顺序是不容质疑的,因为一个叫B,和类必须先摧毁比B,但如何在全球register_shutdown_function功能是否被夹在他们之间吗令人费解的。
根据手册的解析,也可以在退出时调用析构函数。
即使在退出()终止脚本时,析构函数也被调用。
如果在函数中调用退出,如何调用它们
复制代码代码如下所示:
类{
公共功能__construct(){
register_shutdown_function(阵列($,'op '));
出口;
}
公共功能__destruct()
{
回声__class__,'::',__function__,;
}
公共职能部门()
{
回声__class__,'::',__function__,;
}
}
B类{
公共功能__construct()
{
register_shutdown_function(阵列($,'op '));
$ obj =新一;
}
公共功能__destruct()
{
回声__class__,'::',__function__,;
}
公共职能部门()
{
回声__class__,'::',__function__,;
}
}
register_shutdown_function(function(){ echo'global '、';});
新的b;
输出:
复制代码代码如下所示:
全球的
B:OP
答:OP
B::__destruct
答::__destruct
这个序列与上面的第三个例子相似。不同的和令人难以置信的是,B类的析构函数在类A之前执行,在销毁B之后,所有对A的引用都被销毁了吗可以没有它u3002
结论:
1。尽量不要混合register_shutdown_function在脚本__destruct,他们的行为是完全不可预知的。
1,因为对象互相引用,所以我们不知道对象什么时候被销毁。当我们需要输出的内容顺序,我们不应该把内容在析构函数__destruct。
2、尽量不登记register_shutdown_function类,因为它的秩序很难预测(仅调用函数调用这个对象时),和__destruct可以代替register_shutdown_function。
3、如果你需要执行相关的动作脚本时退出,最好是登记register_shutdown_function开头的脚本和发生在一个函数的所有行动。
请改正。