Supongamos que queremos crear un objeto y en un tutorial básico nos enseñan a crear un constructor para dicho objeto con un número de argumentos específico. Supongamos que podemos crear varios constructores, es decir, una función al fin y al cabo, que crea nuestro objeto con los parámetros introducidos. Evidentemente no podemos crear varios constructores con el mismo número de parámetros, pero sí que podemos si el número de parámetros es distinto. Vamos a utilizar un multiconstructor en PHP.

Para ello necesitaremos una función que detecte el número de argumentos que se introducen a la hora de crear el objeto. func_num_args().

Para ilustrarlo con un ejemplo vamos a crear un objeto Vector que definirá la posición en el espacio de un objeto Carga. El vector requiere 3 parámetros de posición (X, Y, Z). El objeto carga será el objeto base para definir los 3 estados de carga en electrostática (protón, neutrón y electrón) y vendrá definido por el tipo de carga y una posición en el espacio. Y vamos a crear dos constructores, el primero introducirá como argumento el mismo objeto de posición Vector y el segundo introducirá los 3 parámetros de posición (positionX, positionY, positionZ).


class Vector {

   function __construct(positionX, positionY, positionZ) {
      $this->X=positionX;
      $this->Y=positionY;
      $this->Z=positionZ;
   }
}

class Charge{

  function __construct() {
      $a = func_get_args();
      $i = func_num_args();
      if (method_exists($this,$f='__construct'.$i)) {
         call_user_func_array(array($this,$f),$a);
      } else{
          /*Do Nothing*/
      }
   }

   function __construct1($Vector) {
      /*Vector Introduced*/
      if (get_class($Vector)=='Vector'){
         $this->X=$Vector->X;
         $this->Y=$Vector->Y;
         $this->Z=$Vector->Z;
      } else{
          /*Do Nothing*/
      }
   }

   function __construct3(positionX, positionY, positionZ) { 
      $this->X=positionX;
      $this->Y=positionY;
      $this->Z=positionZ;
   } 

}

 

 

El primer constructor, no hace otra cosa que llamar a otras funciones que no son realmente constructoras, sino que son métodos internos del objeto que define sus atributos según el número de parámetros gestionados por el constructor real.

Para hacerlo fácil se han llamado a los constructores auxiliares precedidos del número de parámetros que se introducen. Construct1, es el constructor de un parámetro de entrada, pero se podría llamar perfectamente de otra manera. Con la función func_get_args() se recogen los argumentos en un array y se llevan a la nueva función.

Por otra parte se verifica si esa función existe, en este caso valoramos los que tienen 1 y 3 parámetros, pero si introdujéramos 2 parámetros podríamos querer hacer otra acción o no hacer nada.

Observad que en Construct1 lo que introducimos es el objeto vector, por lo que debemos verificar con get_class() que es un objeto definido como vector. Si introdujeramos como entrada otro valor, como un número o un string, nos daría error.

 

Muy bien, ahora vamos a aplicar la misma regla pero con herencia entre objetos, es decir, imaginemos que tenemos un objeto que ya contiene una serie de atributos y creamos uno nuevo que es la extensión del primero. Pero este segundo tiene una entrada de atributos variable.

Para ilustrarlo con un ejemplo ahora creamos un objeto denominado Proton que extenderá el objeto Charge


class Proton extends Charge{

  function __construct() { 
      $a = func_get_args(); 
      $i = func_num_args(); 
      if (method_exists($this,$f='__construct'.$i)) { 
         call_user_func_array(array($this,$f),$a); 
      } else{
          call_user_func_array(array($this,'__constructN'),$a);
      }
   }

   function __construct1($Charge) {
      if (get_class($Charge)=='Charge'){
         parent::__construct($Charge->X,$Charge->Y,$Charge->Z);
         $this->charge='positive'
      } else{
         /*No definition*/
     }
   }

   function __constructN(positionX,positionY,positionZ,value){
      parent::__construct(positionX,positionY,positionZ);
      $this->value=$value;
   }

}

Con ConstructN podremos manejar el constructor sin importar cuantos parámetros son introducidos. Esto nos puede servir por ejemplo para crear una función para concatenar cadenas, independientemente de si la entrada a la función son 10, 100 o 10000.

Ahora solo queda personalizar a nuestro gusto los distintos constructores que tengamos y gestionarlos según los parámetros de entrada. Otro paso más en PHP