example - private public php
¿Puedo confiar en que se llame al método PHP__destruct()? (5)
Hay un error actual con referencias circulares que detiene el método de destrucción que se llama implícitamente. http://bugs.php.net/bug.php?id=33595 Se debe arreglar en 5.3
En PHP5, ¿se garantiza que se invoque el método __destruct () para cada instancia de objeto? ¿Pueden las excepciones en el programa evitar que esto suceda?
Se llamará al destructor cuando se liberen todas las referencias, o cuando finalice la secuencia de comandos. Supongo que esto significa cuando la secuencia de comandos finaliza correctamente. Diría que las excepciones críticas no garantizarían que se llame al destructor.
La documentación de PHP es un poco delgada, pero dice que las excepciones en el destructor causarán problemas.
También vale la pena mencionar que, en el caso de una subclase que tiene su propio destructor, el destructor principal no se llama automáticamente.
Tiene que llamar explícitamente a parent :: __ destruct () desde el método de la subclase __destruct () si la clase principal realiza la limpieza requerida.
Use una función de apagado si quiere estar seguro: register_shutdown_function ()
En mi experiencia los destructores siempre serán llamados en PHP 5.3, pero ten en cuenta que si alguna parte del código llama a exit () o si ocurre un error fatal, PHP llamará a los destructores en "cualquier orden" (creo que el orden real es el orden en memoria o el orden en que la memoria estaba reservada 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.
La documentación de PHP de los destructores dice:
PHP 5 presenta un concepto de destructor similar al de otros lenguajes orientados a objetos, como C ++. Se llamará al método destructor tan pronto como no haya otras referencias a un objeto en particular, o en cualquier orden durante la secuencia de apagado.
Como resultado, si tiene una clase X que contiene una referencia a Y, el destructor de X se puede llamar DESPUÉS de que el destructor de Y ya haya sido llamado. Afortunadamente, la referencia a Y no era tan importante ... Oficialmente, esto no es un error porque ha sido documentado.
Sin embargo, es muy difícil solucionar este problema porque oficialmente PHP no proporciona forma de saber si el destructor se llama normalmente (los destructores se llaman en el orden correcto) o los destructores se llaman en "cualquier orden" donde no se pueden usar datos de objetos referenciados porque esos podrían ya han sido destruidos Uno podría solucionar esta falta de detección utilizando debug_backtrace () y examinando la pila. La falta de una pila normal parece implicar una "secuencia de apagado" con PHP 5.3, pero esto tampoco está definido. Si tiene referencias circulares, los destructores de esos objetos no se llamarán en absoluto con PHP 5.2 o menor y se invocarán en "cualquier orden" durante la "secuencia de apagado" en PHP 5.3 o superior. Para referencias circulares, no existe un orden lógicamente "correcto", por lo que "cualquier" orden es bueno para ellos.
Hay algunas excepciones (esto es PHP después de todo):
- si se llama a
exit()
en otro destructor, no se invocarán los destructores restantes ( http://php.net/manual/en/language.oop5.decon.php ) - si el error
FATAL
ocurre en alguna parte (muchas causas posibles, por ejemplo, tratar de arrojar una excepción desde cualquier otro destructor podría ser una de las causas)
Por supuesto, si el motor PHP golpea la falla de segmentación o se produce algún otro error interno, entonces todas las apuestas están desactivadas.