是的,有......即使这是一个可怕的,可怕的黑客:
$foo = new Foo();
function makeCallable($instance, $method)
{
return function() use ($instance, $method) {
return $instance->{$method}();//use func_get_args + call_user_func_array to support arguments
};
}
那么你可以使用:
$callable = makeCallable($foo, 'bar');
var_dump(is_array($callable));//false
缺点是:
var_dump($callbale instanceof Closure);//true
基本上,不要注意您的可调用对象也是一个数组这一事实,只需在整个代码库中使用类型提示即可:
function foobar(callable $action)
{
return call_user_func($action);
}
应该没问题。
关于为什么你觉得当前的可调用数组是一个缺点:我理解你为什么觉得这不是一件好事。确实没有必要让任何人知道特定的可调用构造是数组、字符串或匿名函数(实际上是 Closure 类的一个实例 - 您可能不想传递的另一个实现细节) .但这正是因为可调用构造有多种形式,callable 类型提示存在:您编写的需要可调用实体的代码不需要关心可调用实体是如何实现的,它只需要知道它可以调用它一条信息:
function handleEvent(callable $action, array $args = null)
{
if ($args) {
return call_user_func_array($action, $args);
}
return call_user_fun($action);
}
我不需要检查$action 是否为字符串(如'strtolower'、Closure 实例或数组)我只是知道我可以调用它