2009-12-07 29 views
10

Estoy en una situación en la que necesito instanciar una clase con argumentos de una instancia de otra clase. Aquí es el prototipo:PHP: cómo crear una instancia de una clase con argumentos de otra clase

//test.php 

class test 
{ 
    function __construct($a, $b, $c) 
    { 
     echo $a . '<br />'; 
     echo $b . '<br />'; 
     echo $c . '<br />'; 
    } 
} 

Ahora, necesito crear una instancia superior a la clase mediante el siguiente cls de clase función:

class myclass 
{ 
function cls($file_name, $args = array()) 
{ 
    include $file_name . ".php"; 

    if (isset($args)) 
    { 
     // this is where the problem might be, i need to pass as many arguments as test class has. 
     $class_instance = new $file_name($args); 
    } 
    else 
    { 
     $class_instance = new $file_name(); 
    } 

    return $class_instance; 
} 
} 

Ahora cuando intento crear una instancia de clase de prueba, mientras que el paso de argumentos a ella:

$myclass = new myclass; 
$test = $myclass->cls('test', array('a1', 'b2', 'c3')); 

da error: Falta argumento 1 y 2; solo se pasa el primer argumento.

Esto funciona bien si instalo una clase que no tiene argumentos en su función de constructor.

Para desarrolladores experimentados de PHP, lo anterior no debería ser un gran problema. Por favor ayuda.

Gracias

+0

No relacionado con su pregunta, pero $ args siempre será 'isset' ya que asigna array() en la definición de la función. Puede estar interesado en 'empty', o' $ args = null'. – Tordek

+0

Lo siento, esto tampoco está relacionado con su pregunta, pero lo que está haciendo no es genial. la respuesta a su pregunta es: deje que su constructor tome una matriz, tenga algunos atributos de clase, luego procese la matriz y asóciela a los atributos de la clase. Pero, de nuevo, estás haciendo algo que no es genial. – DarthVader

+0

la clase de prueba y otras deben ser creadas por otros desarrolladores que usan su propio estilo con argumentos y sin él, por lo que no quiero restringirlos solo para pasar argumentos como matriz a los constructores. – Sarfraz

Respuesta

28

necesita Reflexión http://php.net/manual/en/class.reflectionclass.php

if(count($args) == 0) 
    $obj = new $className; 
else { 
    $r = new ReflectionClass($className); 
    $obj = $r->newInstanceArgs($args); 
} 
+0

Estoy realmente inspirado con el conocimiento de que stereofrog tiene porque la mayoría de la gente ni siquiera sabe acerca de la clase de reflexión y yo mismo no sabía que podemos usar la clase de reflexión para pasar argumentos de esa manera. resolvió mi problema, no pude encontrar la solución durante muchos días. Incluso los desarrolladores más experimentados no fueron capaces de dar una respuesta satisfactoria a mi pregunta, que es muy importante y todos aquí deberían ver ese escenario de la pregunta. De todos modos estoy muy feliz de encontrar una solución a esta pregunta tan importante. Gracias stereofrog :) – Sarfraz

+1

Estaba buscando una solución base sin reflexión, pero parece que tuve que recurrir a esto. Maldito. – yclian

4

puede:

1) Modificar clase de prueba para aceptar una matriz, que contiene los datos que desea pasar.

//test.php 

class test 
{ 
     function __construct($a) 
     { 
       echo $a[0] . '<br />'; 
       echo $a[1] . '<br />'; 
       echo $a[2] . '<br />'; 
     } 
} 

2) iniciado utilizando un método de usuario en lugar del constructor y llaman utilizando la función de call_user_func_array().

//test.php 

class test 
{ 
     function __construct() 
     { 

     } 

     public function init($a, $b, $c){ 
       echo $a . '<br />'; 
       echo $b . '<br />'; 
       echo $c . '<br />'; 
     } 

} 

En su clase principal:

class myclass 
{ 
function cls($file_name, $args = array()) 
{ 
     include $file_name . ".php"; 

     if (isset($args)) 
     { 
       // this is where the problem might be, i need to pass as many arguments as test class has. 
       $class_instance = new $file_name($args); 
       call_user_func_array(array($class_instance,'init'), $args); 
     } 
     else 
     { 
       $class_instance = new $file_name(); 
     } 

     return $class_instance; 
} 
} 

http://www.php.net/manual/en/function.call-user-func-array.php

Por último, se puede dejar el constructor params en blanco y utilizar func_get_args().

//test.php 

class test 
{ 
     function __construct() 
     { 
       $a = func_get_args(); 
       echo $a[0] . '<br />'; 
       echo $a[1] . '<br />'; 
       echo $a[2] . '<br />'; 
     } 
} 

http://sg.php.net/manual/en/function.func-get-args.php

1

Usted podría utilizar call_user_func_array() creo.

o puede dejar la lista de argumentos del constructor, y luego dentro del constructor utilizar este

$args = func_get_args(); 
+0

La primera parte de esta respuesta ayuda a llamar al constructor; la segunda parte podría ayudar en esta clase a hacer que la interfaz sea más agradable (simplemente pase los argumentos en lugar de envolverlos en una matriz). – Tordek

1
class textProperty 
{ 
    public $start; 
    public $end; 
    function textProperty($start, $end) 
    { 
     $this->start = $start; 
     $this->end = $end; 
    } 

} 

$ objeto = new TextProperty ($ inicio, $ final);

no funcionan?

0

La manera más fácil que he encontrado:

if ($depCount === 0) { 
      $instance = new $clazz(); 
     } elseif ($depCount === 1) { 
      $instance = new $clazz($depInstances[0]); 
     } elseif ($depCount === 2) { 
      $instance = new $clazz($depInstances[0], $depInstances[1]); 
     } elseif ($depCount === 3) { 
      $instance = new $clazz($depInstances[0], $depInstances[1], $depInstances[2]); 
     } 

sentimos un poco crudo, pero se debe entender la idea.

Cuestiones relacionadas