<?php
$a = array('a', 'b', 'c', 'd');
foreach ($a as &$v) { }
foreach ($a as $v) { }
print_r($a);
?>
我认为这是一个正常的程序,但这是我得到的输出:
Array
(
[0] => a
[1] => b
[2] => c
[3] => c
)
有人可以向我解释一下吗?
答案 0 :(得分:87)
这是一个记录良好的PHP行为 请参阅php.net的foreach页面上的warning
警告强>
$ value 的引用,即使在 foreach 循环之后,最后一个数组元素仍然存在。建议通过unset()来销毁它。
$a = array('a', 'b', 'c', 'd');
foreach ($a as &$v) { }
unset($v);
foreach ($a as $v) { }
print_r($a);
修改强>
尝试逐步指导实际发生的事情
$a = array('a', 'b', 'c', 'd');
foreach ($a as &$v) { } // 1st iteration $v is a reference to $a[0] ('a')
foreach ($a as &$v) { } // 2nd iteration $v is a reference to $a[1] ('b')
foreach ($a as &$v) { } // 3rd iteration $v is a reference to $a[2] ('c')
foreach ($a as &$v) { } // 4th iteration $v is a reference to $a[3] ('d')
// At the end of the foreach loop,
// $v is still a reference to $a[3] ('d')
foreach ($a as $v) { } // 1st iteration $v (still a reference to $a[3])
// is set to a value of $a[0] ('a').
// Because it is a reference to $a[3],
// it sets $a[3] to 'a'.
foreach ($a as $v) { } // 2nd iteration $v (still a reference to $a[3])
// is set to a value of $a[1] ('b').
// Because it is a reference to $a[3],
// it sets $a[3] to 'b'.
foreach ($a as $v) { } // 3rd iteration $v (still a reference to $a[3])
// is set to a value of $a[2] ('c').
// Because it is a reference to $a[3],
// it sets $a[3] to 'c'.
foreach ($a as $v) { } // 4th iteration $v (still a reference to $a[3])
// is set to a value of $a[3] ('c' since
// the last iteration).
// Because it is a reference to $a[3],
// it sets $a[3] to 'c'.
答案 1 :(得分:3)
第一个
foreach循环不会对数组进行任何更改,正如我们所期望的那样。
但是,它确实会为$v
分配对$a
每个元素的引用,
因此,当第一个循环结束时,$v
实际上是对$a[2]
的引用。
第二个循环开始后,$v
现在分配了每个循环的值
元件。但是,$v
已经是$a[2];
的引用,因此,任何值
分配给它将被自动复制到数组的最后一个元素!
因此,在第一次迭代期间,$a[2]
将变为零,然后是一,然后
再一次,有效地复制到自己身上。为了解决这个问题,你
应始终取消设置您在by-reference foreach中使用的变量
循环 - 或者更好的是,完全避免使用前者。