PHP:为什么只应通过引用传递变量?

时间:2018-09-04 17:08:27

标签: php function pass-by-reference php-7

如果您是PHP开发人员,则很可能已经看到以下通知:

  

注意:/somefile.php中只能通过引用传递变量   在xxx行上

(在Only variables should be passed by reference中处理的问题扩展)

投掷通知示例:

$string = "hi-dude";
echo end(explode('-', $string));

工作示例:

$string = "hi-dude";
$strings = explode('-', $string);
echo end($strings);

说明:

  

只能通过引用传递实变量,而不能返回正确变量的函数。

但是,我想不出发生此通知的充分理由。感觉没有必要,有时需要我写很多额外的代码行。 PHP具有这种奇怪限制的原因是什么? 为什么这个问题甚至存在?

2 个答案:

答案 0 :(得分:2)

end()array_pop()将返回E_NOTICE并显示消息

  

仅变量应通过引用传递

原因是end()需要引用,因为它使当前元素指针指向最后一个元素。

您只需一行即可完成

$string = "this-is-a-sample-text";
echo substr(strrchr($string, '-'), 1);

演示: https://3v4l.org/jO29n

答案 1 :(得分:1)

最后,我找到了一个很好的解释,它帮助我理解了这一点:What's the difference between passing by reference vs. passing by value?

如丹尼尔·普赖登(Daniel Pryden)所述:

  

最简单的说法:

     
      
  • 按值调用意味着您将值作为函数参数传递
  •   
  • 通过引用调用意味着您将变量作为函数参数传递
  •   
     

比喻:

     
      
  • 按价值致电是我在纸上写下一些东西并将其交给您的地方。也许是URL,也许是   战争与和平。不管是什么,它都在一张纸上   我已经给了你,所以现在它实际上就是你的纸了。   您现在可以在那张纸上随意涂鸦,或使用那张纸   纸在其他地方找到东西并弄弄它,   随便。
  •   
  • 以引用方式致电是当我给您我的笔记本上写的东西。您可能会在我的笔记本上涂鸦(也许我   想要你,也许我不想要),然后我随身携带笔记本   无论您在那儿放了些涂鸦。另外,如果你或我   写有关于如何在其他地方找到东西的信息,   您或我都可以去那里弄弄这些信息。
  •   

在这种情况下,“仅应通过引用传递变量”的通知 仍然不合理 ,因为我们只对检索数组的最后一个值感兴趣。但是,函数end()的定义类似于

  

混合端(数组&$ array)

表示通过引用传递的&符号之所以存在是有一定原因的:end()不仅返回数组的最后一个元素,而且还将其内部指针更改为末尾。因此,数组被修改。

如果仅返回数组的最后一个元素而不接触数组,则无需通过引用传递数组,也不会收到此通知。但是end()在某种程度上是错误的功能。

如果我没有理由得到此通知怎么办? 注意,要调用的函数也可能定义错误。就我而言,我有一个这样定义的函数:

/**
 * Flatten an array by one level if only needing a certain key value from a sub array.
 *
 * Example: [["foo"=>"bar","foo"=>"cheese"]]
 * Result: ["bar","cheese"]
 *
 * @param $array: The input array.
 * @param $key: The key to flatupshift. Default is 0.
 * @return $array: The result
 */
private function array_flatupshift(&$array, $key = 0) {
    $a = [];
    foreach ($array as $item) {
        if (is_object($item)) {
            array_push($a, $item->$key);
        } else if (is_array($item)) {
            array_push($a, $item[$key]);
        }
    }
    return $a;
}

这只是错误的函数定义。 因此,如果您还收到这样的通知:检查调用的函数是否正确定义。 在这里通过引用传递没有意义,因为未触摸传递的数组任何方式。因此,函数定义应不带“引用&/”:

private function array_flatupshift($array, $key = 0) {

在某些情况下,如果您知道自己在做什么,则可能会使用错误控制运算符。因此:

$string = "hi-dude";
echo @end(explode('-', $string));

...就可以了我猜是不再需要爆炸的结果了。但是请注意抑制所有可能的错误的缺点。如果我在这里出错,请纠正我。