In php, the sequence of execution of _ destruct and register_shutdown_function is sequential. destruct
According to the php manual.
_ Destruct is
The Destructor is executed when all references to an object are deleted or when the object is explicitly destroyed.
WhileRegister_shutdown_functionYes
Registers a callback to be executed after script execution finishes or exit () is called. Register a callback function that is executed after the script is run or when exit () is called.
Literally speaking, __destruct is at the object level, while register_shutdown_function is at the script level. It is supposed that register_shutdown_function has a higher level and the registered function should be executed at the end. To prove our guesses, we have written a script:
Copy codeThe Code is as follows:
Register_shutdown_function (function () {echo 'global ';});
Class {
Public function _ construct (){
}
Public function _ destruct ()
{
Echo _ class __, ':' ,__ function __, '<br/> ';
}
}
New;
Execution result:
Copy codeThe Code is as follows:
A: :__ destruct
Global
It fully proves our conjecture that it is executed in the order of Object-> script.
But what if we have registered register_shutdown_function in the object? Is it in the same order ?!
Copy codeThe Code is as follows:
Class {
Public function _ construct (){
Register_shutdown_function (function () {echo 'local', '<br/> ';});
}
Public function _ destruct ()
{
Echo _ class __, ':' ,__ function __, '<br/> ';
}
}
New;
Result:
Copy codeThe Code is as follows:
Local
A: :__ destruct
We 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 ?! Unknown, this may need to view the php source code for parsing.
We can expand the scope to view the situation:
Copy codeThe Code is as follows:
Register_shutdown_function (function () {echo 'global', '<br/> ';});
Class {
Public function _ construct (){
Register_shutdown_function (array ($ this, 'op '));
}
Public function _ destruct ()
{
Echo _ class __, ':' ,__ function __, '<br/> ';
}
Public function op ()
{
Echo _ class __, ':' ,__ function __, '<br/> ';
}
}
Class B {
Public function _ construct ()
{
Register_shutdown_function (array ($ this, 'op '));
$ Obj = new;
}
Public function _ destruct ()
{
Echo _ class __, ':' ,__ function __, '<br/> ';
}
Public function op ()
{
Echo _ class __, ':' ,__ function __, '<br/> ';
}
}
$ B = new B;
We register a register_shutdown_function globally, register another function in class AB, and the class also has the destructor. What is the final running result?
Copy codeThe Code is as follows:
Global
B: op
A: op
A: :__ destruct
B: :__ destruct
The result completely subverts our imagination. The register_shutdown_function is first executed no matter whether it is registered in the class or globally, and the execution sequence in the class is the order in which they are registered. If we study the global register_shutdown_function both in front and in the back, it seems that the result is returned, that is, register_shutdown_function is executed first than _ destruct, the global register_shutdown_function is executed before the register_shutdown_function registered in the class.
I cannot accept this result. According to this conclusion, it is hard to say that the script can be executed again after it is completed _ destruct ?! Therefore, I will continue to verify this conclusion-remove the Registry register_shutdown_function in the class and keep the global register_shutdown_function:
Copy codeThe Code is as follows:
Class {
Public function _ destruct ()
{
Echo _ class __, ':' ,__ function __, '<br/> ';
}
}
Class B {
Public function _ construct ()
{
$ Obj = new;
}
Public function _ destruct ()
{
Echo _ class __, ':' ,__ function __, '<br/> ';
}
}
Register_shutdown_function (function () {echo 'global', '<br/> ';});
Output:
Copy codeThe Code is as follows:
A: :__ destruct
Global
B: :__ destruct
The result is confusing. The execution sequence of destructor A and B is unquestionable. Because Class A is definitely destroyed before class B when class A is called in Class B, but how can the global register_shutdown_function be executed in the middle of them ?! Confusing.
According to the manual parsing, The Destructor can also be executed when exit is called.
The Destructor will be called even when the exit () Termination script is used. Calling exit () in the Destructor will stop other close operations.
How can exit be called in a function?
Copy codeThe Code is as follows:
Class {
Public function _ construct (){
Register_shutdown_function (array ($ this, 'op '));
Exit;
}
Public function _ destruct ()
{
Echo _ class __, ':' ,__ function __, '<br/> ';
}
Public function op ()
{
Echo _ class __, ':' ,__ function __, '<br/> ';
}
}
Class B {
Public function _ construct ()
{
Register_shutdown_function (array ($ this, 'op '));
$ Obj = new;
}
Public function _ destruct ()
{
Echo _ class __, ':' ,__ function __, '<br/> ';
}
Public function op ()
{
Echo _ class __, ':' ,__ function __, '<br/> ';
}
}
Register_shutdown_function (function () {echo 'global', '<br/> ';});
$ B = new B;
Output:
Copy codeThe Code is as follows:
Global
B: op
A: op
B: :__ destruct
A: :__ destruct
This order is similar to the third example above. What is different and incredible is that Class B destructor are executed before Class, will all references to Class A be destroyed after Class B is destroyed ?! Unknown.
Conclusion:
1. Try not to mix register_shutdown_function and _ destruct in the script. Their behavior is completely unpredictable.
1. Because the objects are being referenced by each other, we cannot determine when the objects 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 is registered only when this object is called), and _ destruct can replace register_shutdown_function;
3. If you need to execute relevant actions when the script exits, it is best to register register_shutdown_function at the beginning of the script and put all the actions in one function.
Please let us know.
Php destructor _ destruct ()
The Destructor is the code called when the object is destroyed.
When this object is used up, the statements in this function are automatically executed.
Put the code for shutting down the database here. The database connection is closed when the object is destroyed.
In PHP, is the _ destruct () destructor an empty method, or will it perform what work?
You can do some operations, such as closing files and shutting down databases. For example, the word program is silly. It won't be closed when you open the file. You can run it several times and then open the task manager to see that you have to manually turn it off when many words are in the process.