59 votes

Quand __destruct ne sera-t-il pas appelé en PHP?

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

   function __destruct() {
       print "\nDestroying " . $this->name . "\n";
   }
}

$obj = new MyDestructableClass();
 

Lorsque le script ci-dessus se trouve dans un environnement complexe , les __destruct ne seront pas appelés lorsque exit , mais je ne peux pas le reproduire facilement. Est-ce que quelqu'un l'a déjà remarqué?

MODIFIER

Je posterai tout le contenu ici, c'est l'environnement de test de symfony, ce qui signifie que vous pouvez le reproduire facilement si vous connaissez le 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('Y-m-d H:i:s',time()));
$news->setUpdatedAt(date('Y-m-d H:i:s',time()));
$news->save();
exit();
 

78voto

edorian Points 22780

L' __destruct va pas être appelé:

  • Si exit est appelé dans un autre destructeur,
  • Selon la PHP Version: si exit est appelé en register_shutdown_function
  • Si il y a un FATAL error quelque part dans le code
  • Si il y a un exception thrown dans un autre destructeur
  • Si vous essayez de traiter une exception dans un destructeur (PHP >= 5.3.0)

Je suppose que c'est tout ce que je pense dès maintenant

& Ce que Pascal MARTIN a dit. C'est la première étape de débogage qui.

18voto

nickel715 Points 174

Le __destruct ne sera pas non plus appelé si un script s'exécutant sur la CLI et reçoit un SIGTERM (Ctrl + c) :(

14voto

Pascal MARTIN Points 195780

N'ayant pas de sortie sur l'écran ne signifie pas que le destructeur n'est pas appelé : la sortie peut être capturée à l'aide de output_buffering (peut-être que la chaux ne fait que, pour être en mesure de travailler sur elle ? ), et pas d'écho lorsque le script se termine, par exemple.

Pour des fins de test, vous pouvez essayer de l'écrire dans un fichier, dans votre __destruct méthode, au lieu de simplement l'écho du texte.
(Assurez-vous que votre application / PHP a les privilèges requis pour écrire à votre fichier de destination)

(J'ai déjà couru dans des situations où je ne voudrais pas voir la sortie dans un destructeur -- mais il était en fait appelé)

12voto

Comme http://php.net/manual/en/language.oop5.decon.php a déclaré:

 "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."
 

-4voto

Shein Alexey Points 447

Ne connaissez pas la Doctrine, mais vérifiez un point: recherchez les exceptions possibles dans _ construct () / _destruct () car elles peuvent produire des erreurs fatales.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X