【发布时间】:2014-08-08 20:44:43
【问题描述】:
我知道在通过引用循环时不应该修改数组的物理结构,但我需要解释我的代码中发生了什么。我们开始:
$x= [[0],[1],[2],[3],[4]];
foreach ($x as $i => &$upper) {
print $i;
foreach ($x as $j => &$lower) {
if($i == 0 && $j == 2) {
unset($x[2]);
} else if($i == 1 && $j == 3) {
unset($x[3]);
}
}
}
输出为01。令人惊讶的是,对于索引0 和1,外部循环只迭代了两次。我期待输出是014。
我已经阅读了很多关于使用数组引用的危害的博客文章和问题,但没有任何东西可以解释这种现象。我已经为此头疼了好几个小时。
编辑:
上面的代码是最小的可重现代码。一种可能的解释(但不正确)是这样的:
在内部指针设置为索引2 之前,外部循环经过两次迭代。但是循环在索引2 处没有找到任何元素,因此认为没有剩余元素并退出。
这个理论的问题在于它不能完全解释这段代码:
$x= [[0],[1],[2],[3],[4]];
foreach ($x as $i => &$upper) {
print $i;
foreach ($x as $j => &$lower) {
if($i == 0 && $j == 2) {
unset($x[2]);
// No if else here
unset($x[3]);
}
}
}
同理,上面的代码也应该产生01,但它的实际输出是014,正如预期的那样。即使删除了一个系列中的两个项目,php 也知道仍有待迭代的元素。这可能是 php 脚本引擎的错误吗?
【问题讨论】:
-
那你期待什么?
-
添加一些调试输出。将
var_dump($x)放入代码的各个部分,您将确切地看到数组发生了什么。 -
问题是您在 foreach 期间取消设置值并导致 php 中断,因为在其循环期间正在修改 foreach。我会重新考虑你的逻辑,要么复制你取消设置的数组,要么尝试不同的东西。
-
@nl-x 查看我的编辑。到目前为止,我们讨论过的任何理论都无法解释这个案例。
-
@juzerali 我同意你的看法。奇怪