Na navigaci | Klávesové zkratky

How PHP Shutdown and Destructor Calls Occur

Request termination in PHP consists of the following steps performed in the specified order:

  1. Calling all functions registered using register_shutdown_function()
  2. Calling all __destruct() methods
  3. Flushing all output buffers
  4. Terminating all PHP extensions (e.g., sessions)
  5. Shutting down the output layer (sending HTTP headers, clearing output handlers, etc.)

We will focus in more detail on step 2, i.e., the calling of destructors. Of course, object destruction may occur in the first step, i.e., during the calling of registered shutdown functions, for example, if one of the functions held the last reference to an object or if the shutdown function itself was an object.

The calling of destructors occurs as follows:

  1. PHP first attempts to unset objects in the global symbol table.
  2. Then it calls the destructors of all remaining objects.
  3. If execution is stopped for example due to exit(), the remaining destructors are not called.

ad 1) PHP goes through the global symbol table in reverse, i.e., it starts from the variable that was created last and proceeds to the variable that was created first. During this traversal, it unsets all objects with refcount=1. This iteration is performed as long as such objects exist.

Basically, what is done is that a) all unused objects in the global symbol table are removed b) if new unused objects appear, they are also removed c) and so forth. This method of destruction is used so that objects can depend on other objects in the destructor. Usually, this works well if the objects in the global scope do not have complicated (e.g., circular) interdependencies.

The destruction of the global symbol table significantly differs from the destruction of other symbol tables. Therefore, PHP uses a smarter algorithm for the global symbol table that tries to respect the dependencies of objects.

ad 2) Other objects are traversed in the order they were created and their destructor is called. Yes, PHP only calls __destruct, but it actually does not unset the object (nor even changes its refcount). Therefore, if other objects still reference it, it will still be available (even though the destructor has already been called). In a sense, they will be using some sort of “half-destroyed” object.

ad 3) In the case where execution is stopped during the calling of destructors, e.g., due to exit(), the remaining destructors are not called. Instead, PHP marks the objects as already destroyed. An important consequence is that the calling of destructors is not certain. Instances where this happens are rather rare, but it can occur.


You might be interested in

Leave a comment

Text of the comment

(kvůli gravataru)

*kurzíva* **tučné** "odkaz": /--php phpkod(); \--

phpFashion © 2004, 2024 David Grudl | o blogu

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.