可调用数组或字符串上的__invoke() [英] __invoke() on callable Array or String
问题描述
一个人如何编写PHP代码来使用 __ invoke()
来调用所有可调用对象?
How would one write PHP code to call all "Callables" with __invoke()
?
愿望这是通过引用传递,已被 call_user_func [_array]()
弃用。我确实看到那里有一个包, TRex\Reflection\CallableReflection
,但这似乎利用了 call_user_func()
在后台,并且会遇到同样的问题。
The desire here is pass by reference, which is deprecated with call_user_func[_array]()
. I did see that there is a package out there, TRex\Reflection\CallableReflection
, but this seems to utilize call_user_func()
in the background, and would suffer the same issue.
<?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');
这个问题也可能会引起关注,因为有没有一种方法可以过时了,通过引用调用回调?,但我发现当前问题更有趣。
This question could also moonlight as "Is there a way that is not going to be deprecated that you can call a callback with pass by reference?", but I find the current question more interesting.
注意:
主要目标是使回调充当完整功能,并具有所有的优点,主要包括按引用传递,其中 __ invoke($ args,。 ..)
允许。
The primary goal is to have the callback act as a full function, and have all of the niceties of that, primarily including Pass By Reference, which __invoke($args, ...)
allows.
使用 func_get_args()
或 ... $ args
(包装程序上的可变函数)不起作用,因为您仍然会使用 call_user_func_array($ callback,$ arg_array)
,它将不支持通过引用传递。
using func_get_args()
, or ...$args
(variadic function on a wrapper) would not work, as you will still be left with using call_user_func_array($callback, $arg_array)
, which will not support Pass By Reference.
注释2:
我刚刚了解到,您还可以在下一个PHP中使用可变参数调用: function_name(... $ args)
。
I just learned that you can CALL using variadic parameters as well in the next PHP: function_name(...$args)
. Does this support pass by reference?
我们仍然遇到 $ callback_array = array($ object,'method');的问题。
是可调用的,但不能通过 $ callback_array();
来调用,当然也不能通过 $ callback_array(... $ args);
。进一步,我应该澄清的是,问题实际上是关于编写可以在以后的版本中实现这一功能的代码。
Further we still run in to the issue that $callback_array = array($object, 'method');
is a callable, but not by $callback_array();
, and certainly not by $callback_array(...$args);
. Further, I should clarify that the question is really about writing code that will not break in later releases that can do this.
IE:我现在可以编写,运行它明天。
IE: I can write it now, run it tomorrow.
正在寻找潜在客户的机会。
Which is looking dimmer and dimmer of a prospect.
推荐答案
调用类成员很容易实现:
It’s easy to implement for calling class member:
<?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
对于全局范围函数也是应该可行的,但我拒绝尝试实现错误的模式:)
For global scoped function is should be doable as well, but I reject to try to implement wrong patterns :)
这篇关于可调用数组或字符串上的__invoke()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!