是否可以存储来自动态调用的函数的引用,该函数在 PHP 5 中通过引用*返回*


Is it possible to store the reference from a dynamically called function that *returns* by reference in PHP 5?

在 PHP 5 中,有没有办法动态(即通过使用 call_user_funcReflectionFunction::invoke() )调用通过引用返回的函数,并存储它返回的引用,而不会引发通知/警告/错误,也不使用错误控制运算符(@)?

我不是指通过引用传递。通过引用返回是一个完全不同的主题。

举例说明:

$a = (object) array();
$callback = function & () use (&$a) {
    return $a;
};
// no problems, and sure enough $b === $a    
$b = &$callback();
// emits "Strict Standards: Only variables should be assigned by reference"
// but still $b === $a anyway
$b = &call_user_func($callback);

似乎没有办法在 PHP 5.x 中call_user_func()返回引用。但是,根据 PHP 版本,可能会有一些解决方法。

一种方法似乎有效:

$b = &$callback();

正如我们在评论中所讨论的,当我们必须使用配置/可变数量的参数调用$callback()时,这会带来一个问题。如果我们有 PHP 5.6,有一个解决方法,使用 ... (splat) 运算符:

$b = &$callback(...$argArray);

这将按顺序解压缩包含在$argArray中的参数,并将它们作为函数参数传递给$callback()

不幸的是,这仅适用于 PHP 5.6+。

在 PHP 5.6 之前,你可能会坚持使用这样的东西(未经测试):

$argsToEval = array_map(function($key) {
    return '$argArray[' . $key . ']';
}, array_keys($argArray));
$code = sprintf('$b = &$callback(%s);', implode(', ', $argsToEval);
eval($code);

我们都同意这是混乱的。但是,也许可以根据 PHP 版本使用不同的语法,正如您指出需要支持 5.3+ 的那样。我还鼓励您放弃 5.3 和 5.4 支持,因为 5.3 在 2013 年 3 月达到生命周期结束,5.4 在 2015 年 9 月达到生命周期结束。5.5 将在今年 6 月达到生命周期结束。但是,我确实意识到一些用户能够升级的实用性,即使 EoL 已经过去了。