What determines when a class object is destroyed in PHP? What determines when a class object is destroyed in PHP? php php

What determines when a class object is destroyed in PHP?


In PHP all values are saved in so called zvals. Those zvals contain the actual data, type information and - this is important for your question - a reference count. Have a look at the following snippet:

$a = new B; // $a         points to zval(new B) with refcount=1$b = $a;    // $a, $b     point to  zval(new B) with refcount=2 (+1)$c = $b;    // $a, $b, $c point to  zval(new B) with refcount=3 (+1)unset($a);  //     $b, $c point to  zval(new B) with refcount=2 (-1)

As soon as the refcount reaches 0 the zval is freed and the object destructor is called.

Here are some examples of the refcount reaching 0:

  • unseting a variable:

    $a = new B; // refcount=1unset($a);  // refcount=0 => __destruct!

    But:

    $a = new B; // refcount=1$b = $a;    // refcount=2unset($a);  // refcount=1 => no destruct as refcount > 0, even though unset() was called!
  • leaving function (or method) scope

    function a() {    $a = new B; // refcount=1}               // refcount=0 => __destruct! (as $a does not exist anymore)
  • script execution end

    $a = new B; // refcount=1die();      // refcount=0 => __destruct! (on script execution end all vars are freed)// doesn't need to be die(), can be just normal execution end

These obviously are not all conditions leading to a reduction of refcount, but the ones you will most commonly meet.

Also I should mention that since PHP 5.3 circular references will be detected, too. So if object $a references object $b and $b references $a and there aren't any further references to $a or $b the refcounts of both will be 1, but they still will be freed (and __destructed). In this case though the order of destruction is undefined behavior.


PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as C++. The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence. - PHP Manual

If you want to see the process in action, you can run this code here.

<?phpclass A{    public function __construct() { var_dump('Creating: '. get_class($this)); }    public function __destruct() { var_dump('Removing: '. get_class($this)); }}class B extends A {}$A = new A();/* * When this block is called later on */function create_b(){    $B = new B();} // At this point the function scope ends, and since $B is not referenced anymore it's removed.var_dump('B is next');create_b(); // Run above block, create, then destroy bevar_dump('B is now gone');// At this point the PHP file parser ends, $A is destroyed since it's not used anymore


The information is in the manual, albeit somewhat cryptic:

PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as C++. The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence.

Meaning: The destructor will be called when the object gets destroyed (= e.g. unset()), or when the script shuts down.

Additional useful info:

Like constructors, parent destructors will not be called implicitly by the engine. In order to run a parent destructor, one would have to explicitly call parent::__destruct() in the destructor body.

The destructor will be called even if script execution is stopped using exit(). Calling exit() in a destructor will prevent the remaining shutdown routines from executing.