【问题标题】:PHP anonymous function variable as referencePHP匿名函数变量作为参考
【发布时间】:2012-10-11 12:32:30
【问题描述】:

在使用 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() 的第二次尝试会产生(摘自键盘):

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 的错误?

【问题讨论】:

    标签: php function reference anonymous-function


    【解决方案1】:

    我认为这是 PHP 的一个错误,虽然它在技术上是一个 call_user_func 的错误。文档确实提到了这一点,但可能不是很有启发性:

    注意call_user_func()的参数不是通过 参考。

    也许更清楚地说,call_user_func() 的参数不是通过引用传递的(但请注意,从技术上讲,根本不需要说任何东西;这些信息也嵌入在函数签名)。

    在任何情况下,这意味着当call_user_func 最终调用其目标可调用对象时,正在传递的参数的ZVAL(PHP 引擎内部数据结构用于所有类型的值)不会被标记为“被-a-reference";闭包在运行时检查它并抱怨,因为它的签名说参数必须是一个引用。

    在 PHP

     call_user_func($function, &$variable);
    

    但这会产生E_DEPRECATED 警告,因为调用时按引用传递是一个已弃用的功能,并且会在 PHP 5.4 中导致致命错误,因为该功能已被完全删除。

    结论:以这种方式使用call_user_func没有好方法。

    【讨论】:

    • 哦,没有查找call_user_func() 的文档,请阅读有关匿名函数的页面。感谢您的解释。
    • @Jon 我不认为 PHP 5.4 中提供了调用时间传递引用。你应该得到致命错误。
    • @PLB:完全正确,我已经忘记了这一切。感谢您的提醒,我更新了答案。
    【解决方案2】:

    这行得通:

    call_user_func_array($function, array(&$variable));
    

    【讨论】:

      【解决方案3】:

      我用过这段代码

      <?php
      $myfunction = function &($arg=3)
      {
          $arg = $arg * 2;
          return $arg;
      };
      echo $myfunction();
      ?>
      

      工作就像一个魅力。 :)

      【讨论】:

        【解决方案4】:

        如果你这样做会发生什么?

        call_user_func($function, &$variable);
        

        【讨论】:

          猜你喜欢
          • 2012-10-01
          • 2019-11-23
          • 2011-05-11
          • 2012-07-10
          • 2014-03-14
          • 2012-01-14
          相关资源
          最近更新 更多