Question

En PHP5, la méthode __destruct () est-elle garantie d'être appelée pour chaque instance d'objet? Des exceptions dans le programme peuvent-elles empêcher cela?

Était-ce utile?

La solution

Le destructeur sera appelé lorsque toutes les références sont libérées ou lorsque le script se termine. Je suppose que cela signifie que le script se termine correctement. Je dirais que des exceptions critiques ne garantiraient pas l'appel du destructeur.

La documentation PHP est un peu mince, mais elle indique que des exceptions dans le destructeur entraîneront problèmes.

Autres conseils

Il convient également de mentionner que, dans le cas d'une sous-classe qui possède son propre destructeur, le destructeur parent est pas appelé automatiquement.

Vous devez appeler explicitement la parent :: __ destruct () à partir de la méthode de la sous-classe __ destruct () si la classe parent effectue le nettoyage requis.

Selon mon expérience, les destructeurs seront toujours appelés en PHP 5.3, mais sachez que si un élément de code appelle exit () ou si une erreur irrécupérable se produit, PHP appelle les destructeurs dans "any". ordre (je pense que l'ordre réel est l'ordre dans la mémoire ou l'ordre dans lequel la mémoire a été réservée pour les objets. En pratique, cet ordre est presque toujours problématique). Ceci est appelé "séquence d'arrêt". dans la documentation PHP.

La

documentation PHP sur les destructeurs indique:

  

PHP 5 introduit un concept de destructeur similaire à celui d’autres langages orientés objet, tels que C ++. La méthode du destructeur sera appelée dès qu’il n’y aura pas d’autres références à un objet particulier, ou dans un ordre quelconque pendant la séquence d’arrêt.

Par conséquent, si vous avez la classe X qui contient une référence à Y, le destructeur de X peut être appelé APRÈS que le destructeur de Y ait déjà été appelé. Espérons que la référence à Y n’était pas si importante… Officiellement, ce n’est pas un bug car il a été documenté.

Cependant, il est très difficile de résoudre ce problème car, officiellement, PHP ne fournit aucun moyen de savoir si le destructeur est appelé normalement (les destructeurs sont appelés dans le bon ordre) ou les destructeurs sont appelés dans "tout". ordre où vous ne pouvez pas utiliser les données des objets référencés car celles-ci ont peut-être déjà été détruites. On pourrait pallier ce manque de détection en utilisant debug_backtrace () et en examinant la pile. L'absence de pile normale semble impliquer "une séquence d'arrêt". avec PHP 5.3, mais cela aussi n’est pas défini. Si vous avez des références circulaires, les destructeurs de ces objets ne seront pas appelés du tout avec PHP 5.2 ou une version inférieure et seront appelés "tout". ordre pendant la " séquence d'arrêt " en PHP 5.3 ou supérieur. Pour les références circulaires, il n’existe pas de valeur logique "correcte". commandez donc " any " l'ordre est bon pour ceux.

Il y a quelques exceptions (c'est après tout PHP):

  • si exit () est appelé dans un autre destructeur, aucun destructeur restant ne sera appelé ( http://php.net/manual/en/language.oop5.decon.php )
  • si une erreur FATAL se produit n'importe où (de nombreuses causes possibles, par exemple, essayer de lever une exception de tout autre destructeur pourraient être l'une des causes), les destructeurs restants ne seront pas appelés.

Bien sûr, si le moteur PHP rencontre un problème de segmentation ou si un autre bogue interne se produit, tous les paris sont désactivés.

Si vous souhaitez comprendre la mise en oeuvre actuelle de la "séquence d'arrêt", voir https://stackoverflow.com. / a / 14101767 . Notez que cette implémentation pourrait changer dans les futures versions de PHP.

Il existe un bogue courant avec des références circulaires qui empêche la méthode de destruction d'être appelée de manière implicite. http://bugs.php.net/bug.php?id=33595 Cela devrait être corrigé en 5.3

Utilisez une fonction d'arrêt si vous voulez vous en assurer: register_shutdown_function ( )

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top