Evitar que el destructor se llame manualmente

Tengo esta clase:

class Test { private $test = 'ok'; public function doTest() { echo $this->test; } public function __destruct() { $this->test = 'not ok'; } } 

y el siguiente caso de prueba:

 $test = new Test; $test->__destruct(); // I wish this would throw a Fatal Error or something... $test->doTest(); // prints "not ok" 

Lo que quiero lograr es evitar que __destruct() se llame manualmente, de modo que doTest() nunca imprima “no está bien”.

Intenté configurar la visibilidad del destructor en private , pero eso solo conduce a un error fatal en la destrucción del objeto. Una opción sería establecer un indicador $this->destructed en el destructor y luego lanzar una excepción en doTest() si este indicador es verdadero, pero no sería muy eficiente buscar este indicador cada vez que se llame al método. .

Entonces, un destructor private no es posible y una bandera $this->destructed es fea. ¿Hay mejores formas?

Si no desea que se llame al destructor, no lo implemente. En su lugar, use un delegado private para hacer las cosas de apagado.

Tu clase:

 class Test { private $delegate; public function __construct() { $this->delegate = new TestDelegate; } public function doTest() { echo $this->delegate->test."\n"; } } 

Delegar:

 class TestDelegate { public $test = 'ok'; public function __destruct() { $this->test = 'not ok'; echo __METHOD__." called\n"; } } 

Prueba:

 $test = new Test; //$test->__destruct(); // fatal error $test->doTest(); // prints "ok" // TestDelegate::__destruct() gets called automatically 

Ahora, esto puede presentar otros problemas. ¿Cómo asegurarse de que el delegado se registra si una clase hija implementa un constructor y olvida llamar a su constructor padre? ¿Y no rompería las cosas si se llama al constructor varias veces?

Para hacer frente a eso, haga que el constructor sea final y private y use un método de fábrica:

 public static function create() { return new static; }