PHP foreach声明引用:重用迭代器时的意外行为

Fre*_*zin 9 php arrays foreach pass-by-reference

此代码产生意外的输出:

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

echo "\n";
foreach($array as $item)
    echo $item;
Run Code Online (Sandbox Code Playgroud)

输出:

abcde
abcdd
Run Code Online (Sandbox Code Playgroud)

如果&$item用于第二个循环一切正常.

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

zer*_*kms 12

这有助于:

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

var_dump($array);

echo "\n";
foreach($array as $item) {
    var_dump($array);
    echo $item;
}
Run Code Online (Sandbox Code Playgroud)

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

之后,迭代数组并将第4个元素更改为当前元素.因此,在第二次循环的第一次迭代之后,它将是abcda等等abcdd.而在最后一次迭代更改4元至4日,作为dd

  • 事实上,foreach的文档(http://php.net/manual/en/control-structures.foreach.php)专门讨论了这个问题:"$ value和最后一个数组元素的引用甚至在foreach循环之后仍然存在建议用unset()来销毁它." (4认同)
  • @lenzai:`unset($ item);`---只要你不再需要它来防止这种混淆,通常会取消设置引用变量. (3认同)
  • @lenzai:unset**总是**破坏参考.如果你有'$ a = 1; unset($ a);`它会破坏存储在内存中的唯一一个对`1`的引用.只要没有任何其他引用 - 任何变量名称都不再可以访问"1",因此您将其视为"未设置".因此,将未设置视为"某些构造会破坏变量名称和内存之间的互连,但不会修改内存" (3认同)