奇怪的行为的foreach
<?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 )
有人可以向我解释这个吗?
这是logging良好的PHP行为请参阅php.net的foreach页面上的警告
警告
甚至在foreach循环之后, $ value的引用和最后一个数组元素仍然保留。 build议通过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'.
正如我们所期望的那样,第一个foreach循环没有对数组做任何改变。 然而,它确实使$v
被分配了对每个$a
的元素的引用,所以到第一次循环结束时, $v
实际上是对$a[2]
的引用。
只要第二个循环开始, $v
现在被分配每个元素的值。 但是, $v
已经是对$a[2];
的引用$a[2];
因此,分配给它的任何值都将被自动复制到数组的最后一个元素中!
因此,在第一次迭代期间, $a[2]
将变为零,然后是一个,然后再一次被有效地复制到其自身。 要解决这个问题,你应该总是取消你在引用foreach循环中使用的variables,或者更好地避免使用前者。