2010-04-14 20 views
12

Tengo una función que toma argumentos variados, que obtengo de func_get_args().Llamar a un constructor desde argumentos variables con PHP

Esta función necesita llamar a un constructor con esos argumentos. Sin embargo, no sé cómo hacerlo.

Con call_user_func, puede invocar funciones con una matriz de argumentos, pero ¿cómo podría llamar a un constructor a partir de ella? No puedo simplemente pasarle la matriz de argumentos; debe creer que lo llamé "normalmente".

¡Gracias!

+0

Desde PHP 5.6 puede usar _argument unpacking_: 'new SomeClass (... ['arg1', 'arg2']);' – David

Respuesta

20

Para PHP < 5.3 no es fácil hacerlo sin crear primero una instancia de la clase con call_user_func_array. Sin embargo, con Reflection esto es bastante trivial:

$reflection = new ReflectionClass('yourClassName'); 
$instance = $reflection->newInstanceArgs($yourArrayOfConstructorArguments); 
+0

Otra característica de PHP 5.3 que no conocía. Gracias, lo hará. – zneak

+1

Gracias por el ejemplo. Probablemente esta sea la primera cosa en el manual de PHP que he encontrado que no fue explicada muy bien. –

+5

@zneak, 'ReflectionClass :: newInstanceArgs' no es nuevo en PHP 5.3, lo tenemos desde 2006 cuando fue lanzado con PHP 5.1.3. @byronh, ¿hay algo en particular que haya encontrado que no está bien explicado o se refiere a las partes etiquetadas como "indocumentadas"? (No dude en enviarme un correo electrónico, [email protected]) – salathe

-2

Si por alguna razón no se puede utilizar ReflectionClass::newInstanceArgs Aquí hay otra solución utilizando eval():

function make_instance($class, $args) { 
    $arglist = array(); 
    $i = 0; 
    foreach($args => &$v) { 
     $arglist[] = $n = '_arg_'.$i++; 
     $$n = &$v; 
    } 
    $arglist = '$'.implode(',$',$arglist); 
    eval("\$obj = new $class($arglist);"); 
    return $obj; 
} 
$instance = make_instance('yourClassName', $yourArrayOfConstructorArguments); 

Tenga en cuenta que el uso de esta función le permite pasar argumentos por referencia al constructor, que no es aceptable con ReflectionClass::newInstanceArgs.

+0

¿Qué pasa con esta respuesta? ¿Algún comentario? ¿Es solo por 'eval'? He indicado claramente al principio que esta es una solución alternativa que utiliza 'eval' – DUzun

Cuestiones relacionadas