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

2022-06-16 00:00:00 function pass-by-reference php 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有此奇怪限制的原因是什么?为什么会存在此问题?


解决方案

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

正如Daniel Pryden所说:

最简单地说:

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

比喻:

  • Call by Value指的是我在一张纸上写下一些东西,然后递给你。可能是一个URL,也可能是 战争与和平。不管它是什么,它都在一张纸上, 我已经给了你,所以现在它实际上是你的一张纸。 你现在可以自由地在那张纸上涂鸦,或者使用那张纸 去别的地方找点东西摆弄, 随便了。
  • Call by Reference指的是我把我的笔记本给你,上面写着一些东西。你可以在我的笔记本上乱涂乱画(也许我 想你,也许我不想),然后我保留了我的笔记本,和 不管你在那里写了什么涂鸦。还有,如果你或我 写了关于如何在其他地方找到东西的信息, 你或我都可以去那里摆弄那些信息。

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

混合结束(ARRAY&;$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));

.会很好的。我猜是爆炸的结果不再需要了。但是,请注意隐藏所有可能的错误的缺点。如果我说错了,请纠正我。

相关文章