En PHP5, es el __destruct() método garantizado para ser llamados para cada instancia de objeto? Puede excepciones en el programa de evitar que esto suceda?

InformationsquelleAutor Casey Watson | 2008-09-30

5 Comentarios

  1. 36

    El destructor será llamado cuando el todas las referencias son liberados, o cuando el script finaliza. Supongo que esto significa que cuando el script finaliza correctamente. Yo diría que la crítica excepciones no garantizaría el destructor a ser llamado.

    La Documentación de PHP es un poco más delgada, pero sí dice que las Excepciones en el destructor va a causar problemas.

    • Puedo decir, que las Excepciones durante el proceso de cierre puede causar fallas de segmentación.
    • También, llamar a exit() dentro de un destructor que ya está en el exit() secuencia puede terminar el proceso sin más destructores que se llama.
    • Lo siento, no me podía imaginar su ejemplo. Le pueden elaborar? @JasonCohen
    • Si usted necesita el destructor de ser llamado, incluso en el caso de php fatal error, a continuación, registrar como cierre de controlador en el constructor: public function __construct() { register_shutdown_function(array($this, '__destruct')); }. El costo de esta solución es que el objeto de referencia (y el objeto en sí) existe hasta el final de la ejecución del script de php. Aún así, no hay caso, entonces es digno de ella – por ejemplo, enorme tmp eliminación de archivos en el destructor.
  2. 43

    También vale la pena mencionar que, en el caso de una subclase que tiene su propio destructor, el padre destructor es no se llama de forma automática.

    Tienes que llamar explícitamente parent::__destruct() de la subclase __destruct() método de la clase padre hace cualquier limpieza necesaria.

    • Creo que esto es cierto sólo cuando el niño de clase implementa su propio __destruct(), de lo contrario el padre de __destruct() será llamado.
  3. 13

    En mi experiencia, los destructores será llamado siempre en PHP 5.3, pero se advirtió que si alguna pieza de código llama a exit() o si se produce un error grave, PHP llamada destructores en «cualquier» orden (creo que el orden es el orden, en la memoria o en el orden de la memoria, estaba reservado para los objetos. En la práctica, este orden es casi siempre problemático). Esto se conoce como «secuencia de apagado» en la documentación de PHP.

    Documentación de PHP de los destructores dice:

    PHP 5 se presenta un destructor concepto similar a la de otros lenguajes orientados a objetos, como C++. El método destructor se llamará tan pronto como no hay otras referencias a un objeto en particular, o en cualquier orden durante la secuencia de apagado.

    Como resultado, si usted tiene la clase X que contiene una referencia a la Y, el destructor de X puede ser llamado DESPUÉS de que el destructor de Y ya ha sido llamado. Con suerte, la referencia Y no era importante… Oficialmente este no es un bug, ya que se ha documentado.

    Sin embargo, es muy difícil solucionar este problema porque oficialmente PHP proporciona ninguna manera de saber si el destructor es llamado normalmente (los destructores son llamados en el orden correcto) o destructores son llamados en «cualquier» orden donde no se puede utilizar los datos de referencia a objetos debido a que éstos ya han sido destruidos. Uno podría solucionar esta falta de detección utilizando debug_backtrace() y el examen de la pila. La falta de pila normal parece implicar «secuencia de apagado» con PHP 5.3, pero esto, también, es indefinido. Si usted tiene referencias circulares, los destructores de los objetos no ser llamado a todos con PHP 5.2 o menor y será llamado en «cualquier» orden «durante la secuencia de cierre» en PHP 5.3 o superior. Para las referencias circulares, no existe una lógica orden «correcto» por lo que «cualquier» orden es bueno para las personas.

    Hay algunas excepciones (este es el PHP, después de todo):

    • si exit() se llama en otro destructor, cualquier resto de los destructores no se llama (http://php.net/manual/en/language.oop5.decon.php)
    • si FATAL error se produce en cualquier lugar (muchas causas posibles, por ejemplo, tratando de lanzar una excepción de cualquier otra destructor podría ser una de las causas), cualquier resto de los destructores no se llama.

    Por supuesto, si el motor de PHP golpea a un fallo de segmentación o algún otro interno error se produce, entonces todas las apuestas están apagadas.

    Si quieres entender actual aplicación de la «secuencia de cierre», ver https://stackoverflow.com/a/14101767. Tenga en cuenta que esta aplicación puede cambiar en futuras versiones de PHP.

    • Fundamentos de PHP: «yo estoy pegado a la implementación actual, porque creo que es el mejor trade-off. –Andi». Fuente: mail-archive.com/[email protected]/msg06393.html
    • Básicamente hay dos grupos de programadores: (1) los codificadores uso de las variables globales en los destructores y (2) los codificadores que no usar variables globales en los destructores Y correctamente las marcas de seguridad de las dependencias mediante el uso de referencias de objeto a objetos dependientes. Porque PHP intenta orientar el extremo inferior se abastece para (1) en (2). El grupo (2) queda con incorrectamente el código de trabajo y no de manera oficial para solucionar el problema.
    • Véase también: stackoverflow.com/questions/2385047/…
  4. 8

    El uso de una función de apagado si quieres ir seguro: register_shutdown_function()

    • A partir de la documentación: «Varias llamadas a register_shutdown_function() se puede hacer, y cada uno será llamado en el mismo orden en que fueron registrados. Si la llamada exit() dentro de una registrados función de apagado, el procesamiento se detiene completamente y no otros registrado funciones de apagado será llamado.» No hay ninguna garantía de que su función de apagado será llamado si alguna otra función de apagado se ejecuta antes que el tuyo.

Dejar respuesta

Please enter your comment!
Please enter your name here