Let's say that we have class CFoo
. In the following example when is CFoo::__destruct()
called?
function MyPHPFunc()
{
$foo = new CFoo();
. . .
// When/where/how does $foo get destroyed/deleted?
}
In this example would the destructor be called when the script exits the scope of MyPHPFunc
because $foo
would no longer be accessible?
PHP Destructor: PHP Destructor method is used to destroy objects or release their acquired memory. A destructor is called automatically when the object is created. Usually, it is called at end of the script. The destructor method does not take any arguments, The destructor does not return any data type.
An object is an instance of a class. Using the PHP unset() function, we can delete an object. So with the PHP unset() function, putting the object that we want to delete as the parameter to this function, we can delete this object.
PHP has a garbage collector which will take care of removing objects from memory once they are not being used any longer.
Example# __construct() is the most common magic method in PHP, because it is used to set up a class when it is initialized. The opposite of the __construct() method is the __destruct() method. This method is called when there are no more references to an object that you created or when you force its deletion.
In PHP all values are saved in so called zval
s. Those zval
s 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
:
unset
ing a variable:
$a = new B; // refcount=1
unset($a); // refcount=0 => __destruct!
But:
$a = new B; // refcount=1
$b = $a; // refcount=2
unset($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=1
die(); // 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 refcount
s of both will be 1
, but they still will be freed (and __destruct
ed). 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.
<?php
class 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 be
var_dump('B is now gone');
// At this point the PHP file parser ends, $A is destroyed since it's not used anymore
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With