【问题标题】:How to avoid call-time pass-by-reference deprecated error in PHP?如何避免 PHP 中的调用时传递引用已弃用错误?
【发布时间】:2010-11-06 13:10:49
【问题描述】:

我正在尝试减少发送到我的 apache 服务器日志的警告

一个警告是:

调用时传递引用已被弃用。

我很难想象为什么不推荐使用它,因为它是一个非常有用的编程功能,基本上我是这样做的:

public function takeScriptsWithMarker(&$lines, $marker) {

    ...
}

我反复调用这个函数,从它那里取回结果并处理它们,但也让数组 $lines 通过反复发送到这个方法来建立。

  1. 要重新编程这将是广泛的。
  2. 我不想只是“关闭警告”,因为我想查看其他警告。

因此,由于引用调用已被弃用,实现此模式功能的“可接受方式”是什么:即将字符串数组发送到方法中,让它们成为被方法改变了,然后继续使用那个数组?

【问题讨论】:

    标签: php


    【解决方案1】:

    其实你定义函数的方式是没有问题的。你调用函数的方式有问题。所以对于你的例子,而不是像这样称呼它:

    takeScriptsWithMarker(&$lines, $marker);
    

    你可以这样称呼它:

    takeScriptsWithMarker($lines, $marker); // no ampersands :)
    

    所以该功能仍然可用。但我不知道这种变化背后的原因。

    【讨论】:

    • “我不知道这个变化背后的原因。”。长话短说,函数负责决定通过引用传递什么,而不是调用者。当调用者可以通过引用传递任意参数时,这可能会导致函数作者没有准备好的副作用。
    • 来自 allow_call_time_pass_reference 的文档:“出于代码清洁的原因,不推荐在函数调用时通过引用传递参数。如果函数没有声明参数由引用。为防止副作用,最好仅在函数声明中指定哪些参数通过引用传递。"
    • @Frank,感谢您的澄清。不好的部分是,只看一个函数调用,你不知道这些参数中的任何一个都可以通过引用传递。因此,您可能会在不知情的情况下对函数产生副作用。在我看来,在函数定义和函数调用中都需要有与号的要求会好得多。
    • @Ionut:仅仅查看函数的签名是否足以消除疑问?如果您没有源代码或文档,那么您遇到的问题比复制 & 更严重,恕我直言
    • @Adriano,是的,但我也在考虑函数名称很好地传达其意图的情况,所以我觉得不需要查找函数定义。此外,函数的返回值可能是正确的,所以没有理由去查找函数定义……至少在开始时。
    【解决方案2】:

    就像前面的回答中提到的,问题是在调用时间,而不是定义时间..所以你可以定义一个函数:

    function foo(&$var1,$var2,$var3=null){
        // procesing here
    }
    

    然后调用为:

    $return = foo($invar1,$invar2);
    

    您的第一个因瓦是通过引用传递的,第二个不是。

    当您尝试这样调用时会出现错误:

    $return = foo(&$invar1,$invar2);
    

    【讨论】:

      【解决方案3】:

      您可以在php.ini 文件中将allow_call_time_pass_reference 设置为true。但这是一个 hack。

      【讨论】:

        【解决方案4】:

        你可以传递一个带有引用的数组:

        public function takeScriptsWithMarker(array(&$lines, $marker))
        

        这应该只需要在另一端进行少量重构。

        【讨论】:

          【解决方案5】:

          您可以传入数组,让它对其进行操作,然后“返回”它,而不是弄乱原始引用。只包含返回和分配应该不会太难。

          public function takeScriptsWithMarker($lines, $marker) {
              //...
              return $lines;
          }
          

          用法:

          $lines = takeScriptsWithMarker($lines, $marker);
          

          【讨论】:

            猜你喜欢
            • 2011-06-07
            • 2012-06-03
            • 2013-03-23
            • 2013-05-21
            • 1970-01-01
            • 2013-11-17
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多