name = "MyDestruc...">

When will __destruct not be called in PHP?

class MyDestructableClass { function __construct() { print "\nIn constructor\n"; $this->name = "MyDestructableClass"; } function __destruct() { print "\nDestroying " . $this->name . "\n"; } } $obj = new MyDestructableClass(); 

When the above script is in the complex environment, __destruct will not be called when exit , but I cannot play it easily. Has anyone ever noticed this

EDIT

I posted all the material here, it is a symfony test environment, which means you can easily reproduce it if you are familiar with the framework:

 require_once dirname(__FILE__).'/../bootstrap/Doctrine.php'; $profiler = new Doctrine_Connection_Profiler(); $conn = Doctrine_Manager::connection(); $conn->setListener($profiler); $t = new lime_test(0, new lime_output_color()); class MyDestructableClass { function __construct() { print "\nIn constructor\n"; $this->name = "MyDestructableClass"; } function __destruct() { print "\nDestroying " . $this->name . "\n"; } } $obj = new MyDestructableClass(); $news = new News(); $news->setUrl('http://test'); $news->setHash('http://test'); $news->setTitle('http://test'); $news->setSummarize('http://test'); $news->setAccountId(1); $news->setCategoryId(1); $news->setThumbnail('http://test'); $news->setCreatedAt(date('Ymd H:i:s',time())); $news->setUpdatedAt(date('Ymd H:i:s',time())); $news->save(); exit(); 
+47
php destructor
Mar 05 '10 at 6:51
source share
6 answers

__destruct will not be called:

  • If exit is called in another destructor
  • Depending on the PHP version: if exit is called in the shutdown function registered in register_shutdown_function
  • If the code has a fatal error
  • If another destructor throws an exception
  • If you try to handle the exception in the destructor (PHP> = 5.3.0)

Guess what I can think now

& What Pascal MARTIN said. This is the first step in debugging this.

+62
Mar 05 '10 at 9:12
source share

The lack of output on the screen does not mean that the destructor is not being called: ouptut can be captured using output_buffering (maybe lime it to be able to work on it?), And not echo when the script ends, for example.

For testing purposes, you can try writing the file to your __destruct method instead of just repeating some text.
(Just make sure your application / PHP has the necessary permissions to write to the destination file)

(I already faced situations when I did not see the conclusion made in the destructor, but it was actually called)

+13
Mar 05 '10 at 8:01
source share

As the PHP documentation says:

The destructor will be called even if the script is terminated using exit() . Calling exit() in the destructor will prevent the rest of the shutdown procedures from being executed.

+9
Oct 24 '12 at 20:00
source share

The __destruct method __destruct also not be called if a script is running in the CLI and receives SIGTERM ( Ctrl + C )

+9
May 30 '14 at 14:08
source share

I know I'm a little late to the party, but for people who also want to get __destruct to execute when CTRL + C and / or fatal errors occur, you can try this (below is a test case):

Index.php

 <?php // Setup CTRL+C and System kill message handler // The only signal that cannot be caught is the SIGKILL (very hard kill) declare(ticks = 1); // Required else it won't work. pcntl_signal(SIGTERM, 'close'); // System kill (Unhappy Termination) pcntl_signal(SIGINT, 'close'); // CTRL+C (Happy Termination) // Shutdown functions will be executed even on fatal errors register_shutdown_function('close'); function close($signal = null) // only pcntl_signal fills $signal so null is required { // Check if there was an fatal error (else code below isn't needed) $err = error_get_last(); if(is_array($err)) { foreach(array_keys($GLOBALS) as $key) { if(in_array($key, ['_GET', '_POST', '_COOKIE', '_FILES', '_SERVER', '_REQUEST', '_ENV', 'GLOBALS'])) continue; // This will automatically call __destruct unset($GLOBALS[$key]); } } } // Example class blah { private $id = ''; public function __construct() { $this->id = uniqid(); // note this piece of code, doesn't work on windows! exec('mkdir /tmp/test_'.$this->id); } public function __destruct() { // note this piece of code, doesn't work on windows! exec('rm /tmp/test_'.$this->id.' -R'); } } // Test $a = new blah(); $b = new blah(); $c = new blah(); $d = new blah(); $e = new blah(); $f = new blah(); $g = new blah(); $h = new blah(); $i = new blah(); $j = new blah(); $k = new blah(); $l = new blah(); $m = new blah(); $n = new blah(); $o = new blah(); $p = new blah(); $q = new blah(); $r = new blah(); $s = new blah(); $t = new blah(); $u = new blah(); $v = new blah(); $w = new blah(); $x = new blah(); $y = new blah(); $z = new blah(); // The script that causes an fatal error require_once(__DIR__.'/test.php'); 

test.php

 <?php // this will create a parse (E_PARSE) error. asdsaddsaadsasd 

Note: calling exceptions for an exception or an exception in destructors or a shutdown function will cause the script to terminate immediately.

+1
Aug 6 '15 at 7:54
source share

Not familiar with the Doctrine, but check one point: check for possible exceptions in __construct () / __ destruct (), they can lead to fatal errors.

-four
Mar 05 2018-10-10T00:
source share



All Articles