如何编写PHP代码以使用__invoke()
调用所有“Callables”?
这里的愿望是通过引用传递,不推荐使用call_user_func[_array]()
。我确实看到有一个包,TRex\Reflection\CallableReflection
,但这似乎在后台使用call_user_func()
,并且会遇到同样的问题。
<?php
function passthrough_invoke(callable $callback) {
return $callback->__invoke();
}
function passthrough_user(callable $callback) {
return call_user_func($callback);
}
function test_func() { return "func_string\n"; };
class test_obj {
function test_method() {
return "obj_method\n";
}
}
print_r("Call User Func Works:\n");
echo passthrough_user(function() { return "func_closure\n"; });
echo passthrough_user(array(new test_obj, 'test_method'));
echo passthrough_user('test_func');
print_r("\n__invoke dies:\n");
echo passthrough_invoke(function() { return "func_closure\n"; });
echo passthrough_invoke(array(new test_obj, 'test_method'));
echo passthrough_invoke('test_func');
这个问题也可以说是“有没有一种不会被弃用的方法,你可以通过引用来调用回调?”,但我发现当前的问题更有趣。
备注:
主要目标是让回调充当一个完整的功能,并具有其中的所有细节,主要包括__invoke($args, ...)
允许的Pass By Reference。
使用func_get_args()
或...$args
(包装器上的可变参数函数)将不起作用,因为您仍将使用call_user_func_array($callback, $arg_array)
,这将不支持Pass By Reference。< / p>
备注2:
我刚刚了解到你可以在下一个PHP中使用可变参数进行调用:function_name(...$args)
。这种支持是否通过引用传递?
此外,我们仍然遇到$callback_array = array($object, 'method');
可以调用但不是$callback_array();
,而不是$callback_array(...$args);
的问题。此外,我应该澄清,问题实际上是关于编写代码,这些代码在以后的版本中不会破坏,可以做到这一点。
IE:我现在可以写了,明天运行。
对于潜在客户来说,这看起来越来越暗淡。
答案 0 :(得分:0)
调用类成员很容易实现:
<?php
function passthrough_invoke(callable $callback) {
return $callback->__invoke();
}
function passthrough_user(callable $callback) {
return call_user_func($callback);
}
function test_func() { return "func_string\n"; };
class test_obj {
public function test_method() {
return "obj_method\n";
}
}
class CallableWrapper {
private $inst, $meth;
public function __construct( $inst, $meth ) {
$this->inst = $inst;
$this->meth = $meth;
}
public function __invoke() {
echo $this->inst->{$this->meth}();
}
}
print_r("Call User Func Works:\n");
echo passthrough_user(function() { return "func_closure\n"; });
echo passthrough_user(array(new test_obj, 'test_method'));
echo passthrough_user('test_func');
print_r("\n__invoke rocks:\n");
echo passthrough_invoke( function() { return "func_closure\n"; } );
echo passthrough_invoke(
new CallableWrapper( new test_obj, 'test_method' )
);
// ⇒
// __invoke rocks:
// func_closure
// obj_method
对于全局范围的函数也应该是可行的,但我拒绝尝试实现错误的模式:)