PHP匿名函数变量作为参考

时间:2012-10-11 12:32:31

标签: php function reference anonymous-function

在使用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

小提琴:Codepad @ Viper-7

写这篇文章时,我考虑过call_user_func_array()fiddle here,但会产生同样的错误。

我对引用有什么不对,或者这是PHP的错误吗?

4 个答案:

答案 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);