2010-04-14 3 views
12

J'ai une fonction qui prend des arguments variadiques, que j'obtiens de func_get_args().Appel d'un constructeur à partir d'arguments variables avec PHP

Cette fonction doit appeler un constructeur avec ces arguments. Cependant, je ne sais pas comment le faire.

Avec call_user_func, vous pouvez appeler des fonctions avec un tableau d'arguments, mais comment appelez-vous un constructeur? Je ne peux pas simplement passer le tableau des arguments à cela; il faut croire que je l'ai appelé "normalement".

Merci!

+0

Depuis PHP 5.6, vous pouvez utiliser _argument unpacking_: 'new SomeClass (... ['arg1', 'arg2']);' – David

Répondre

20

Pour PHP < 5.3 ce n'est pas facile à faire sans d'abord créer une instance de la classe avec call_user_func_array. Cependant, avec Reflection cela est assez trivial:

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

Une autre fonctionnalité de PHP 5.3 que je ne connaissais pas. Merci, ça va le faire. – zneak

+1

Merci pour l'exemple. C'est probablement la première chose dans le manuel PHP que j'ai trouvé qui n'a pas été très bien expliqué. –

+5

@zneak, 'ReflectionClass :: newInstanceArgs' n'est pas nouveau en PHP 5.3, nous l'avons depuis 2006 avec PHP 5.1.3. @byronh, y a-t-il quelque chose en particulier que vous n'avez pas bien expliqué ou faites-vous référence aux parties "non documentées"? (N'hésitez pas à m'envoyer un email, [email protected]) – salathe

-2

Si pour une raison quelconque, vous ne pouvez pas utiliser ReflectionClass::newInstanceArgs ici est une autre solution en utilisant 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); 

Notez que cette fonction vous permet de passer des arguments par référence au constructeur, ce qui n'est pas acceptable avec ReflectionClass::newInstanceArgs.

+0

Quel est le problème avec cette réponse? Des commentaires? Est-ce juste à cause de 'eval'? J'ai clairement indiqué au début que c'est une solution alternative utilisant 'eval' – DUzun

Questions connexes