2010-10-30 12 views
5

Estoy pasando todas mis llamadas a una función de mapeo principal y luego debería llamar dinámicamente a otra función basada en una cadena (hasta esta parte, las cosas son fáciles) el problema es que quiero pasar argumentos a la segunda función y estos parámetros pueden variar. se da (no debería cambiarse) En el siguiente:función dinámica argumentos

function test1($x){ 
    echo $x; 
} 

function test2($x, $y){ 
    echo $x * $y; 
} 

y ahora viene la función de mapeo

function mapping ($str){ 
     switch ($str){ 
      case 'name1': 
       $fn_name = 'test1'; 
       $var = 5; 
       break; 
      case 'name2': 
       $fn_name = 'test2'; 
       $var = 5; 
       break; 
     } 
     $this->{$fn_name}($var); 
} 

Y entonces esto va a ejecutar el mapeo:

$this->mapping('name1'); 
$this->mapping('name2'); // This one will crash as it need two variables 

Por supuesto, el arriba se simplifica para enfocarse en el problema y no en el propósito del código. El problema es cuando la función tiene más de un argumento (lo que puede suceder fácilmente). Estoy esperando tener la caja del interruptor y en función de cómo se llenan los parámetros de la caja, la línea $this->{$fn_name}($var); debería funcionar.

Puede por favor asesorarme o darme ideas, sabiendo que la estructura de las funciones (test1, test2) NO se puede cambiar. Yo no puedo repente empezar a utilizar func_get_args() o func_get_arg()

Respuesta

5

Puede utilizar ReflectionFunction y su método invokeArgs() para pasar las variables en una matriz:

function mapping ($str) { 
    switch ($str) { 
     case 'name1': 
      $fn_name = 'test1'; 
      $fn_args = array(5); 
      break; 
     case 'name2': 
      $fn_name = 'test2'; 
      $fn_args = array(5, 10); 
      break; 
    } 

    $function = new ReflectionFunction($fn_name); 
    $function->invokeArgs($fn_args); 
} 
+1

Tu sugerencia es genial cansado y funcionó bien. pero después de explorar en php.net si se encuentra call_user_func_array() y resolvió mi problema a la perfección, pero todavía se lo debo todo :) – bhefny

+2

FYI - ReflectionFunction no funcionará en los métodos de clase - instancia o estática – phirschybar

2

Desde mapping() en el código parece ser un método de clase, reemplazarlo con:

public function __call($method, $args) 
{ 
    // possibly validate $method first, e.g. with a static map 
    return call_user_func_array($method, $args); 
} 

Ejemplos:

function foo($foo) { echo $foo; } 
function bar($foo, $bar) { echo "$foo - $bar"; } 

$this->foo('foo'); // outputs 'foo' 
$this->bar('foo', 'bar'); // outputs 'foo - bar' 

Esto significa que su clase no debe tener los métodos foo() o bar() para invocar el __call().

Sin embargo, parece ser un problema bastante complicado. Probablemente haya una solución más elegante para lo que estás tratando de lograr. :)

Cuestiones relacionadas