sobrecarga ejemplos constructores clases __destruct __construct php destructor

ejemplos - ¿Cuándo__destruct no se llamará en PHP?



php constructor parameters (6)

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

Cuando la secuencia de comandos anterior se encuentra en un entorno complejo , la __destruct no se llamará cuando exit , pero no puedo reproducirla fácilmente. ¿Alguna vez alguien se ha dado cuenta de esto?

EDITAR

Voy a publicar todo el contenido aquí, es el entorno de prueba de Symfony, lo que significa que puedes reproducirlo fácilmente si estás familiarizado con el marco:

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();


Como dice la documentación de PHP :

Se llamará al destructor incluso si la ejecución del script se detiene con exit() . Llamar a exit() en un destructor evitará que se ejecuten las rutinas de cierre restantes.


El hecho de no tener un resultado en la pantalla no significa que no se invoque el destructor: el ouptut se puede capturar usando output_buffering (¿quizás lime lo haga, para poder trabajar en él?) , Y no se repite cuando termina el script, por ejemplo .

Para fines de prueba, puede intentar escribir en un archivo, en su método __destruct , en lugar de hacer eco de algún texto.
(Solo asegúrese de que su aplicación / PHP tenga los privilegios necesarios para escribir en su archivo de destino)

(Ya me encontré con situaciones en las que no vería la salida realizada en un destructor, pero en realidad se llamó)


El método __destruct tampoco se __destruct si el script se ejecuta en CLI y recibe un SIGTERM ( Ctrl + C )


La __destruct no se llamará:

  • Si se llama a exit en otro destructor
  • Según la versión de PHP: si se llama a la exit en una función de apagado registrada con register_shutdown_function
  • Si hay un error fatal en algún lugar del código
  • Si otro destructor arroja una excepción
  • Si intenta manejar una excepción en un destructor (PHP> = 5.3.0)

Supongo que es todo lo que puedo pensar en este momento

& Qué dijo Pascal MARTIN. Ese es el primer paso para depurar eso.


No está familiarizado con la Doctrina, pero verifique un punto: verifique las posibles excepciones en __construct () / __ destruct () pueden producir errores fatales.


Sé que llego un poco tarde a la fiesta, pero para las personas que también __destruct que __destruct se ejecute cuando se producen errores CTRL + C y / o fatales, puede intentarlo (a continuación se muestra un caso de prueba):

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

Nota: si se llama a la salida o se lanzan excepciones en los destructores o en las funciones de apagado, la secuencia de comandos finalizará inmediatamente.