【问题标题】:PHP foreach statement by reference: unexpected behaviour when reusing iteratorPHP foreach 引用语句:重用迭代器时的意外行为
【发布时间】:2011-09-11 09:24:15
【问题描述】:

此代码产生意外的输出:

$array=str_split("abcde");
foreach($array as &$item)
    echo $item;

echo "\n";
foreach($array as $item)
    echo $item;

输出:

abcde
abcdd

如果在第二个循环中使用&$item,一切正常。

我不明白这段代码会如何影响$array 的内容。我可以认为隐含的unset($header) 会删除最后一行,但是双重dd 来自哪里?

【问题讨论】:

    标签: php arrays foreach pass-by-reference


    【解决方案1】:

    这可能会有所帮助:

    $array=str_split("abcde");
    foreach($array as &$item)
        echo $item;
    
    var_dump($array);
    
    echo "\n";
    foreach($array as $item) {
        var_dump($array);
        echo $item;
    }
    

    正如您在最后一次迭代之后看到的那样,$item 指的是$array (e) 的第四个元素。

    之后您遍历数组并将第 4 个元素更改为当前元素。所以在第二个循环的第一次迭代之后,它将是abcda,等等abcdd。在最后一次迭代中,您将第 4 个元素更改为第 4 个,如 dd

    【讨论】:

    • 谢谢。无论如何在第一个循环之后从第 4 个元素中“分离” $item 吗?
    • @lenzai: unset($item); --- 只要您不再需要它以防止此类混淆,取消设置引用变量是一种常见的做法。
    • 我的错误,我认为 unsset($item 会删除 $array[4]。我想我错了。
    • @lenzai: unset always 会破坏引用。如果您有$a = 1; unset($a);,它会破坏内存中对1 的唯一一个引用。只要没有任何其他引用 - 1 不再可以使用任何变量名访问,因此您将其视为“未设置”。因此,可以将 unset 视为“破坏变量名和内存之间互连但不修改内存的某种构造”
    • 其实foreach的文档(php.net/manual/en/control-structures.foreach.php)专门讲了这个:“$value的引用和最后一个数组元素在foreach循环之后仍然存在。建议通过以下方式销毁它未设置()。“
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 2021-08-12
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多