Home >Backend Development >PHP Tutorial >The order of execution of __destruct and register_shutdown_function in php_PHP tutorial
is based on the analysis of the php manual.
__destruct is
The destructor is executed when all references to an object are deleted or when the object is explicitly destroyed.
while register_shutdown_function is
Registers a callback to be executed after script execution finishes or exit() is called.
Literally understood, __destruct is at the object level, while register_shutdown_function is at the entire script level. Register_shutdown_function should be of a higher level, and the functions it registers should also be executed last. To confirm our guess, we write a script:
The code is as follows:
Execution result:
The code is as follows:
Completely confirmed our guess, it was executed in the order of object->script.
But what if we register register_shutdown_function in the object? Is it still the same order? !
The code is as follows:
Result:
Copy the code The code is as follows:
You can see that register_shutdown_function is called first, and finally the __destruct of the execution object. This indicates that the function registered by register_shutdown_function is treated as a method in the class? ! I don't know, this may require viewing the php source code to parse it.
We can expand the scope to see the situation:
The code is as follows:
我们在全局注册一个register_shutdown_function函数,在类AB中又各注册了一个,而且类中分别还有析构方法。最后运行结果会怎样呢?
代码如下:
结果完全颠覆了我们的想像,register_shutdown_function函数无论在类中注册还是在全局注册,它都是先被执行,类中执行的顺序就是它们被注册的先后顺序。如果我们再仔细研究,全局的register_shutdown_function函数无论放在前面还是后面都是这个结果,事情似乎有了结果,那就是register_shutdown_function比__destruct先执行,全局的register_shutdown_function函数又先于类中注册的register_shutdown_function先执行。
且慢,我无法接受这个结果,按照这样的结论,难道说脚本已经结束后还可以再执行__destruct?!因此,我还要继续验证这个结论---去掉类中注册register_shutdown_function,而保留全局register_shutdown_function:
代码如下:
输出:
代码如下:
结果令人茫然,A、B两个类的析构函数执行顺序无可质疑,因为B中调用了A,类A肯定比B先销毁,但全局的register_shutdown_function函数又怎么夹在它们中间被执行?!费解。
按照手册的解析,析构函数也可在调用exit时执行。
The destructor is called even when the script is terminated using exit(). Calling exit() in the destructor will abort the remaining shutdown operations.
If exit is called in a function, how are they called?
The code is as follows:
Output:
The code is as follows:
This sequence is similar to the third example above. What is different and incredible is that the destructor of class B is executed before class A. Is it true that all references to class A are destroyed only after B is destroyed? ! unknown.
Conclusion:
1. Try not to mix register_shutdown_function and __destruct in scripts. Their behavior is completely unpredictable.
1. Because objects refer to each other, we cannot know when the object will be destroyed. When the content needs to be output in order, the content should not be placed in the destructor __destruct;
2. Try not to register register_shutdown_function in the class, because its order is difficult to predict (the function will only be registered when this object is called), and __destruct can completely replace register_shutdown_function;
3. If you need to perform relevant actions when the script exits, it is best to register register_shutdown_function at the beginning of the script and put all actions in a function.