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

前端 未结 2 1721
轮回少年
轮回少年 2021-01-06 01:37

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 d

2条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-06 02:31

    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

提交回复
热议问题