通过call_user_func_array将命名参数传递给php函数

Wag*_*age 12 php function

当尝试使用任意参数集调用子类中的函数时,我遇到以下问题:

class Base{

    function callDerived($method,$params){
        call_user_func_array(array($this,$method),$params);
    }
}

class Derived extends Base{
    function test($foo,$bar){
        print "foo=$foo, bar=$bar\n";
    }
}

$d = new Derived();
$d->callDerived('test',array('bar'=>'2','foo'=>1));
Run Code Online (Sandbox Code Playgroud)

输出:

foo=2, bar=1
Run Code Online (Sandbox Code Playgroud)

哪个...并不是我想要的 - 除了使用func_get_args的索引顺序重新组合数组之外,有没有办法实现这一目标?是的,当然,我可以简单地传递整个数组并在函数中处理它...但这不是我想要做的.

谢谢

dec*_*eze 22

不.PHP不支持命名参数.仅考虑参数的顺序.您可以使用ReflectionClass检查函数参数名称,将代码本身分开,但最后您还是需要使用它来重新排序数组.


小智 8

股票PHP类ReflectionMethod是你的朋友.

例:

class MyClass { 
    function myFunc($param1, $param2, $param3='myDefault') { 
        print "test"; 
    } 
}

$refm = new ReflectionMethod('MyClass', 'myFunc');

foreach ($refm->getParameters() as $p) 
    print "$p\n";
Run Code Online (Sandbox Code Playgroud)

结果如下:

Parameter #0 [ <required> $param1 ]
Parameter #1 [ <required> $param2 ]
Parameter #2 [ <optional> $param3 = 'myDefault' ]
Run Code Online (Sandbox Code Playgroud)

此时,您知道目标函数的参数名称.使用此信息,您可以修改方法' callDerived ',并且可以根据参数名称将数组重新排序为call_user_func_array.


Vin*_*nce 5

好消息,我有同样的担忧(我在PHP中寻找命名参数,就像Python一样),并找到了这个有用的工具:https://github.com/PHP-DI/Invoker

这使用反射API从一个数组中提供带有一些参数的可调用对象,并使用可选参数defaults用于未在数组中定义的其他参数.

$invoker = new Invoker\Invoker;
$result = $invoker->call(array($object, 'method'), array(
    "strName"  => "Lorem",
    "strValue" => "ipsum",
    "readOnly" => true,
    "size"     => 55,
));
Run Code Online (Sandbox Code Playgroud)

玩得开心


Ray*_*rea 5

更新:PHP 8 现在支持命名参数。call_user_func_array如果您传递关联数组,它就会起作用。所以你可以简单地这样做:

<?php

function myFunc($foo, $bar) {
    echo "foo=$foo, bar=$bar\n";
}

call_user_func_array('myFunc', ['bar' => 2, 'foo' => 1]);
// Outputs:  foo=1, bar=2
Run Code Online (Sandbox Code Playgroud)

在您的代码中,您会很高兴知道不需要更改任何内容。只需升级到 PHP 8,它就会按您的预期工作