在使用Laravel框架时,更具体的 - 表单宏,我偶然发现了一个奇怪的错误。
起初,我认为Laravel有点不对劲,但后来我把所有事情都搞定了:
<?php
// placeholder function that takes variable as reference
$function = function(&$reference)
{
// append to variable
$reference = $reference . ':' . __METHOD__;
};
// test with straight call
$variable = 'something';
$function($variable);
echo $variable;
// test with call_user_func(), that gets called in Laravels case
$variable = 'something'; // reset
call_user_func($function, $variable);
echo $variable;
第一次调用$function
时,call_user_func()
的第二次调用产生(摘自Codepad):
Warning: Parameter 1 to {closure}() expected to be a reference, value given
PHP Warning: Parameter 1 to {closure}() expected to be a reference, value given
写这篇文章时,我考虑过call_user_func_array()
:fiddle here,但会产生同样的错误。
我对引用有什么不对,或者这是PHP的错误吗?
答案 0 :(得分:8)
我认为这是PHP的一个错误,虽然它在技术上是call_user_func
的错误。文档确实提到了这一点,但也许不是一种非常有启发性的方式:
请注意,
call_user_func()
的参数不会传递 参考
可能更清楚地说 call_user_func()
的参数不是通过引用传递的(但请注意,从技术上讲,没有必要说任何内容;这些信息也是嵌入式的在函数签名中。)
无论如何,这意味着当call_user_func
最终调用其目标可调用时,传递的参数的ZVAL
(所有类型值的PHP引擎内部数据结构)不是标记为“作为参考”;闭包在运行时检查它并抱怨,因为它的签名表明参数必须是引用。
在PHP&lt; 5.4.0可以通过引用使用call-time传递来解决这个问题:
call_user_func($function, &$variable);
但是这会产生E_DEPRECATED
警告,因为通过引用传递的调用时间是一个不推荐使用的功能,并且将在PHP 5.4中导致致命错误,因为该功能已被完全删除。
结论:没有好方法以这种方式使用call_user_func
。
答案 1 :(得分:3)
这有效:
call_user_func_array($function, array(&$variable));
答案 2 :(得分:2)
我使用了这段代码
<?php
$myfunction = function &($arg=3)
{
$arg = $arg * 2;
return $arg;
};
echo $myfunction();
?>
像魅力一样工作。 :)
答案 3 :(得分:1)
如果你这样做会怎么样?
call_user_func($function, &$variable);