foreach 的奇怪行为
Posted
技术标签:
【中文标题】foreach 的奇怪行为【英文标题】:Strange behavior Of foreach 【发布时间】:2011-06-25 13:12:27 【问题描述】:<?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
)
谁能给我解释一下?
【问题讨论】:
"i think, its normal prog but web i saw op.........then ....ahh wat is it" 是什么意思? @Bart Kiers:他似乎在发呆。 Unintentional destruction of php array element? 的可能重复项 这是对这种行为的最好解释:schlueters.de/blog/archives/141-References-and-foreach.html Strange behaviour after loop by reference - Is this a PHP bug?的可能重复 【参考方案1】:这是有据可查的 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'.
【讨论】:
@Manish Trivedi:请参阅 警告 部分了解为什么会发生这种情况。你的程序没有问题。 很好的解释!谢谢:D 我必须记住一个作为参考/欺骗,所有其他关于使用 foreach 参考的答案都没有像你在这里所做的那样解释它! 在你的unset($v);
中,为什么$v
可以在foreachs 范围之外访问? :o
@nawfal - 不明白这个问题.... PHP 局部变量范围在函数内,而不仅仅是在循环内
@MarkBaker 谢谢。你回答了我的问题。刚刚开始掌握 PHP 特性 :)【参考方案2】:
第一个
正如我们所期望的那样,foreach 循环不会对数组进行任何更改。
但是,它确实会导致为$v
分配对$a
的每个元素的引用,
因此,当第一个循环结束时,$v
实际上是对$a[2]
的引用。
第二个循环一开始,$v
就被赋予了每个循环的值
元素。但是,$v
已经是对 $a[2];
的引用,因此,任何值
分配给它的会自动复制到数组的最后一个元素中!
因此,在第一次迭代期间,$a[2]
将变为 0,然后变为 1,然后
再一次,被有效地复制到自己身上。为了解决这个问题,你
应始终取消设置您在按引用 foreach 中使用的变量
循环——或者,更好的是,完全避免使用前者。
【讨论】:
以上是关于foreach 的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 jQuery foreach 进入多维数组?奇怪的行为