【问题标题】:What are the advantages of a pass by reference iterator in a foreach loop in PHP?在 PHP 的 foreach 循环中通过引用迭代器的优点是什么?
【发布时间】:2010-07-16 01:42:07
【问题描述】:

我刚刚读到这个answer by Bill Karwin

请注意,$node 是通过引用传递的。

我一直认为在那里创建的变量只是暂时的,并且只存在到循环结束(或者它可能仍然设置为最后一次迭代 - 我还没有测试过)。

那么,让它通过引用传递有什么好处呢?

我确定有一个,但我还想不通。

【问题讨论】:

    标签: php foreach


    【解决方案1】:

    这与更快或更高效无关。

    PHP 实现了写时复制,因此变量可能会引用同一内存区域直到您更改它的值。然后,当您更改变量时,PHP 会根据您是按值访问还是按引用访问来决定是否创建副本。

    按值访问——对变量的更改会创建一个副本:

    $a = array("abc");
    
    foreach ($a as $element) {
      $element = "def";
    }
    
    print_r($a);
    
    Array
    (
        [0] => abc
    )
    

    通过引用访问——对变量的更改会影响原始副本:

    foreach ($a as &$element) {
      $element = "def";
    }
    
    print_r($a);
    
    Array
    (
        [0] => def
    )
    

    请注意,PHP 5 中的所有对象都是通过引用访问的,没有使用& 运算符。
    这是使用对象的好理由!

    在 PHP 中使用引用要非常小心,因为它们会产生令人困惑的效果。

    请务必阅读这篇博客:Do not use PHP references,作者是 PHP 核心开发人员 Johannes Schlüter

    【讨论】:

    • 小心! $foo = array(1, 2, 3); foreach($foo as &$bar) { $bar++; } $bar = 99; echo $foo[2]; -- 这会打印“99”。 "$bar" 在循环结束后仍然是一个引用。如果你不小心,你可以而且会在脚上开枪。
    【解决方案2】:

    优点是可以直接操作数组。

    foreach ($array as $key => $node) {
        $array[$key]['foo'] = 'bar';
    }
    

    可以像这样变得更短更高效:

    foreach ($array as &$node) {
        $node['foo'] = 'bar';
    }
    

    在这种情况下,$node 不是数组条目内容的副本,而是对实际数组条目的引用;不管你对它做什么,你对数组做什么。

    【讨论】:

    • +1 谢谢,我刚刚意识到我使用了前者,现在可以更有效率。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 2011-03-18
    • 2013-11-19
    • 2010-12-05
    • 1970-01-01
    • 2013-01-04
    • 2019-05-23
    相关资源
    最近更新 更多