tags:

views:

32

answers:

2

I'm passing all my calls to a main mapping function and then it should dynamically call other function based on a string (until this part, things are easy) the problem is that I want to pass arguments to the second function and these parameters may vary. The following is given (should not be changed):

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

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

and now comes the mapping function

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);
}

And then this will run the mapping:

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

Of course the above is simplified to focus on the problem not the purpose of the code. The problem is when the function has more than one argument (which can easily happen). I'm expecting to have the switch case and based on how the case parameters are filled, the line $this->{$fn_name}($var); should work.

Can you please advise or give me ideas, knowing that the functions (test1, test2) structure can NOT be changed. I can NOT suddenly start using func_get_args() or func_get_arg()

Thank you.

+3  A: 

You can use ReflectionFunction and its invokeArgs() method to pass the variables in an array:

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);
}
Tatu Ulmanen
A: 

Since mapping() in your code seems to be a class method, replace it with:

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

Examples:

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

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

This means that your class shouldn't have the methods foo() or bar() for the __call() to be invoked.

Seems to be a pretty complicated problem though. There's probably a more elegant solution to what you're trying to achieve? :)

Till