Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I pass an associative array as an argument to ReflectionMethod::invokeArgs?

Tags:

php

reflection

Is it possible to pass parameters as an associative array in ReflectionMethod::invokeArgs? This would allow me to pass the arguments in a different order than declared.

For example:

class A
{
    public function someMethod($a, $b)
    {
        return sprintf("a - %s, b - %s", $a, $b);
    }
}

$rm = new ReflectionMethod('A', 'someMethod');
echo $rm->invokeArgs(new A(), array('b' => 1, 'a' => 2));
like image 916
Noxt Avatar asked Dec 27 '11 21:12

Noxt


2 Answers

You can do this by overwriting the invokeArgs method and implementing the functionality you need (in your case it looks like you want to use named arguments):

class ReflectionMethodA extends ReflectionMethod
{
    public function invokeArgs($object, Array $args = array())
    {
        $parameters = $this->getParameters();
        foreach($parameters as &$param) 
        {
            $name = $param->getName();
            $param = isset($args[$name]) ? $args[$name] : $param->getDefaultValue();
        }
        unset($param);

        return parent::invokeArgs($object, $parameters);
    }
}

$rm = new ReflectionMethodA('A', 'someMethod');

echo $rm->invokeArgs(new A(), array('b' => 1, 'a' => 2));

Output:

a - 2, b - 1

Edit: An improved (supporting both named and numbered arguments as well as passing by reference) and more flexible variant (to be used for any callback) is the following class, taking any valid callback as parameter in it's constructor.

Usage:

$rc = new ReflectedCallback(array(new A(), 'someMethod'));
echo $rc->invokeArgs(array('b' => 1, 'a' => 2));

Gist

like image 86
hakre Avatar answered Sep 30 '22 02:09

hakre


No, there's nothing in the manual page that suggests you can use an associative array to re-order arguments by name.

like image 23
Lightness Races in Orbit Avatar answered Sep 30 '22 02:09

Lightness Races in Orbit