"; } function __construct() { $this->a=debug_backtrace(); # <" /> "; } function __construct() { $this->a=debug_backtrace(); # <" /> "; } function __construct() { $this->a=debug_backtrace(); # <"/>

__destruct and debug_backtrace() in PHP

230 views Asked by At

I don't understand why

class test {
 
    
    function __destruct() {
        echo "I am the destructor<br>";
    }
    
    function __construct() {
         $this->a=debug_backtrace(); # <=== THIS LINE
    }
}
$myclass=new test();
unset($myclass);
echo "Last Line<br>";

out- and incommenting this line changes the order of the echo output. Why is the destructor not called by the unset() when the contsructor did a debug_backtrace() before?

1

There are 1 answers

0
Björn Steinbrink On

By default, the backtrace returned by debug_backtrace() includes the function arguments including the implicit $this argument as object. Therefore, there's a cycle where the test instance referenced by $myclass also indirectly references itself, thereby keeping itself alive.

If you use ... = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) that cycle is no longer present and the destructor is called right after the unset($myclass) call.

You can also call gc_collect_cycles() after unset, which will run the cycle collector and free the test instance, calling the destructor in the process.