Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

The sequence in which _ _ destruct and register_shutdown_function are executed in the script in php

2025-01-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the relevant knowledge of "the sequence of execution of _ _ destruct and register_shutdown_function in php". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

_ _ destruct is

The destructor executes when all references to an object are deleted or when the object is explicitly destroyed.

And register_shutdown_function is.

Registers a callback to be executed after script execution finishes or exit () is called. Register a callback function that is executed when the script finishes running or when exit () is called.

Literally, _ _ destruct is at the object level, while register_shutdown_function is at the entire script level, which is supposed to be a higher level of register_shutdown_function, and the functions it registers should be executed last. To confirm our guess, we wrote a script:

The copy code is as follows:

Register_shutdown_function (function () {echo 'global';})

Class A {

Public function _ construct () {

}

Public function _ destruct ()

{

Echo _ _ class__,'::',__function__,''

}

}

New A

Execution result:

The copy code is as follows:

A::__destruct

Global

It fully confirms our guess that it is executed in the order of object-> scripts.

But what if we register register_shutdown_function with the object? Is it still the same order?!

The copy code is as follows:

Class A {

Public function _ construct () {

Register_shutdown_function (function () {echo 'local',';})

}

Public function _ destruct ()

{

Echo _ _ class__,'::',__function__,''

}

}

New A

Results:

The copy code is as follows:

Local

A::__destruct

You can see that register_shutdown_function is called first, and then 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, it may take a look at the php source code to parse.

We can expand the scope to see what's going on:

The copy code is as follows:

Register_shutdown_function (function () {echo 'global',';})

Class A {

Public function _ construct () {

Register_shutdown_function (array ($this, 'op'))

}

Public function _ destruct ()

{

Echo _ _ class__,'::',__function__,''

}

Public function op ()

{

Echo _ _ class__,'::',__function__,''

}

}

Class B {

Public function _ construct ()

{

Register_shutdown_function (array ($this, 'op'))

$obj = new A

}

Public function _ destruct ()

{

Echo _ _ class__,'::',__function__,''

}

Public function op ()

{

Echo _ _ class__,'::',__function__,''

}

}

B = new B

We register a register_shutdown_function function globally, another in the class AB, and a destructor in the class. What will be the result of the final run?

The copy code is as follows:

Global

B::op

A::op

A::__destruct

B::__destruct

The result completely subverts our imagination that register_shutdown_function functions are executed first, whether they are registered in the class or globally, and the order in which they are registered is the order in which they are registered. If we take a closer look, this is the result of both the global register_shutdown_function function and the global register_shutdown_function function, which seems to have a result, that is, register_shutdown_function executes before _ _ destruct, and the global register_shutdown_function function executes before the register_shutdown_function registered in the class.

Wait a minute, I can't accept this result. According to this conclusion, it is possible to execute _ _ destructcodes after the script has finished! Therefore, I will continue to verify this conclusion-remove the registered register_shutdown_function from the class and leave the global register_shutdown_function:

The copy code is as follows:

Class A {

Public function _ destruct ()

{

Echo _ _ class__,'::',__function__,''

}

}

Class B {

Public function _ construct ()

{

$obj = new A

}

Public function _ destruct ()

{

Echo _ _ class__,'::',__function__,''

}

}

Register_shutdown_function (function () {echo 'global',';})

Output:

The copy code is as follows:

A::__destruct

Global

B::__destruct

The result is confusing, there is no doubt about the execution order of the destructors of class An and B, because class An is called in B, class A must be destroyed before B, but how can the global register_shutdown_function function be executed between them?! I don't understand.

As parsed in the manual, destructors can also be executed when exit is called.

The destructor is called even when the script is terminated with exit (). Calling exit () in the destructor will abort the rest of the shutdown operation.

If you call exit in a function, how are they called?

The copy code is as follows:

Class A {

Public function _ construct () {

Register_shutdown_function (array ($this, 'op'))

Exit

}

Public function _ destruct ()

{

Echo _ _ class__,'::',__function__,''

}

Public function op ()

{

Echo _ _ class__,'::',__function__,''

}

}

Class B {

Public function _ construct ()

{

Register_shutdown_function (array ($this, 'op'))

$obj = new A

}

Public function _ destruct ()

{

Echo _ _ class__,'::',__function__,''

}

Public function op ()

{

Echo _ _ class__,'::',__function__,''

}

}

Register_shutdown_function (function () {echo 'global',';})

B = new B

Output:

The copy code is as follows:

Global

B::op

A::op

B::__destruct

A::__destruct

This order is similar to the third example above, but 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 An are destroyed after class B is destroyed?! can make nothing of it.

Conclusion:

1. Try not to mix register_shutdown_function with _ _ destruct in scripts, as their behavior is completely unpredictable.

1. Because objects are referencing each other, we cannot tell when the objects are destroyed. When we need to output content sequentially, we should not put the content in the destructor _ _ destruct

2. Try not to register register_shutdown_function in the class, because its order is difficult to predict (functions are registered only 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 the actions in one function.

This is the order in which _ _ destruct and register_shutdown_function are executed in the script in php. Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report