Romper el constructor

¿Hay una manera de evitar la creación de objetos dentro de su constructor, de modo que:

$object = new Foo(); echo $object; // outputs: NULL 

No, no es posible; la new palabra clave siempre devuelve una instancia de la clase especificada, sin importar lo que intente devolver desde el constructor. Esto se debe a que, cuando se llama a su constructor, PHP ya ha terminado de asignar memoria para el nuevo objeto. En otras palabras, el objeto ya existe en ese punto (de lo contrario, no hay ningún objeto al que llamar el constructor).

En su lugar, podría generar errores o lanzar excepciones desde el constructor, y manejarlos en consecuencia.

 class Foo { public function __construct() { throw new Exception('Could not finish constructing'); } } try { $object = new Foo(); } catch (Exception $e) { echo $e->getMessage(); } 

Imposible, pero puedes proxificar la creación .

  

Simplemente lanza una excepción:

 throw new Exception('thou shalt not be born!'); 

Podrías implementar una fábrica para hacer la creación del objeto por ti. Si está utilizando PHP 5.3.0+, tendrá acceso a una función llamada Enlace estático tardío que facilita esta tarea.

  loadSuccess = (mt_rand (0, 99) > 49); } static public function factory ($foo, $bar, $baz) { $objClass = get_called_class (); $obj = new $objClass ($foo, $bar, $baz); if ($obj -> loadSuccess) { return ($obj); } } } class MySubClass extends MyObject { protected function __construct ($foo, $bar, $baz) { parent::__construct ($foo, $bar, $baz); if ($this -> loadSuccess) { echo ('Hello, I\'ma ' . get_called_class () . '
'); } } } class MySubSubClass extends MySubClass { protected function __construct ($foo, $bar, $baz) { parent::__construct ($foo, $bar, $baz); if ($this -> loadSuccess) { echo ($foo * $bar * $baz . '
'); } } } $o1 = MyObject::factory (1, 2, 3); // Base class $o2 = MySubClass::factory (4, 5, 6); // Child class $o3 = MySubSubClass::factory(7, 8, 9); // Descendent class var_dump ($o1); var_dump ($o2); var_dump ($o3); ?>

Si está utilizando una versión de PHP anterior a 5.3.0, entonces las cosas se complican un poco más, ya que el enlace estático tardío y get_called_class () no están disponibles. Sin embargo, PHP 5 admite la reflexión y puede usarlo para emular el enlace estático tardío. Alternativamente, puede implementar una clase de fábrica separada y pasarle un argumento que le diga qué tipo de objeto desea inicializar.

Otro enfoque es hacer que su constructor lance una excepción si falla y manejarlo con un bloque catch. Sin embargo, este método puede ser un poco complicado si lo está haciendo mucho y realmente debería usarse solo cuando normalmente espera que la creación de objetos tenga éxito (en otras palabras, si la falla de creación es una circunstancia excepcional).

El enfoque de fábrica tiene ventajas adicionales, por ejemplo, puede contener un caché de objetos que ya ha creado y si intenta crear el mismo objeto dos veces, simplemente le pasará una referencia al objeto ya inicializado en lugar de crear uno nuevo. . Esto elimina la memoria y la sobrecarga de procesamiento inherente a la creación de objetos, especialmente si la creación implica una tarea que requiere mucho tiempo, como una consulta SQL compleja.

Si intenta detener la creación de instancias de un objeto dependiendo de algunas condiciones, ¿por qué no crear una condición antes de que incluso llegue al PHP new y cree una instancia de la clase?

Lo que quiero decir es, di en tu ejemplo:

 $object = new Foo(); echo $object; // outputs: NULL 

Podría envolverlo en una función que haga el trabajo de validación por usted o simplemente una statement if si solo va a crear una instancia de la clase una vez.

Me gusta esto:

 if(conditions_to_meet){ $object = new Foo(); } else $object = NULL; 

si necesita crear una instancia de eso varias veces, envuélvalo en una función y pase los parámetros a su clase.

Espero que esto ayude.