【问题标题】:PHP foreach() is amending the arrayPHP foreach() 正在修改数组
【发布时间】:2012-04-18 05:04:10
【问题描述】:

以下显示数组中的值的代码在包装在 foreach() 中时会显示不同的结果,而不是在我使用简单的 for 循环时。 for 循环提供了正确的数据,但 foreach() 似乎在每次迭代时都在修改输入数组。

$arr = array_merge($arr1, $arr2);

for ($x = 0; $x < count($arr); $x++) {
    echo $arr[90]['circread_value'];
}

foreach ($arr as $unused) {
    echo $arr[90]['circread_value'];
}

for 循环的输出一遍又一遍地是相同的值(如预期的那样):

1382429.00
1382429.00
1382429.00
1382429.00
...

foreach() 的输出显示数组中的第 91 个元素随着每次迭代而变化:

56256.00
45652.00
50726.00
317896.00
...

这怎么可能?

注意:我知道上面的代码是人为的(显然在 foreach() 中我实际上想要做进一步的处理并引用我正在迭代的数组的每个元素,而不仅仅是查看第 91 个元素.) 我只是将代码缩减为一些简单的东西(作为我调试的一部分,就像在这里发布一样!)

一些进一步的信息:

  • $arr 已通过 array_merge 创建了两个 91 元素数组以创建一个 182 元素数组。
  • 我看到的行为只发生在第 91 个元素上 - 如果我回显 $arr[89]['circread_value'] 或 $arr[91]['circread_value'],我会从 foreach() 获得一致的值也是。
  • 我在 foreach() 中看到的(看似随机的)值实际上是来自数组中其他元素的值(数组在开始 foreach 之前的样子)

输入数组($arr1 和 $arr2)可以在这里找到:http://pastebin.com/wQN8XXu2

感谢您的任何见解。不要犹豫,询问更多信息。

【问题讨论】:

  • 有趣。 var_dump 每次循环迭代的输出是什么?
  • 你是说你已经用你的数据运行了上面的exact代码,你看到了这个问题吗?
  • 我是unable to repeat这个... PHP版本请
  • @DaveRandom 是的 - 我已经运行了这个确切的代码。看起来很奇怪吧?我会跳到“PHP 肯定是错误的”,但是危险信号警告我这更有可能是我的错误!
  • @DaveRandom 请注意,还有更多代码(用于设置数组等 - 它是大型站点的一部分)。数组内容与我在这里展示的不完全一样(因为有更多的子元素而不仅仅是 'blah',显然还有 182 个元素需要考虑。)我可以把这个发给你吗?

标签: php arrays foreach


【解决方案1】:

foreach 修改内部数组指针,for 没有,因为它希望您提供整数偏移量,如 http://us3.php.net/manual/en/control-structures.foreach.php 中所证明的那样

“由于 foreach 依赖于内部数组指针,因此在循环内更改它可能会导致意外行为。”

【讨论】:

  • foreach modifies the internal array pointer - 不,它没有。 foreach 与数组的副本一起使用,这就是为什么您要使用引用(例如foreach ($arr as &amp;$val))来修改源数组。无论如何,这在这里无关紧要,他正在静态引用这些值。
  • 是的:php.net/manual/pt_BR/control-structures.foreach.php。问题是,它只会在循环开始时重置一次。在这种情况下,它没有任何区别。
  • @drgomesp 我同意这个案子,除了“这个案子”看起来像小说,据我所知,我想我会找到任何实际错误的根源真实代码(这显然不是)
  • 同样,答案有一个有效的论据,但对于这种情况是不正确的。
  • 是的,但它会在每次迭代时推进该指针,并且在 foreach 结束时指针位于末尾(如 this 所示)。因此,如果您在每次迭代时将一个新项推送到数组中,则该指针永远不会到达末尾,因为即使您在最后一个元素上,到该迭代结束时也会有另一个。
【解决方案2】:

你的代码兄弟有问题。

我刚刚tested this:

$arr = array(
    0 => array('blah' => 123.42),
    1 => array('blah' => 5488.87),
    90 => array('blah' => 669874.923)
);

for ($x = 0; $x < count($arr); $x++) {
    echo $arr[90]['blah'] . PHP_EOL;
}

foreach ($arr as $unused) {
    echo $arr[90]['blah'] . PHP_EOL;
}

而且输出很好:

669874.923
669874.923
669874.923
669874.923
669874.923
669874.923

您介意向我们展示更多您的代码吗?

【讨论】:

  • 谢谢 - 我将转储真实数组的全部内容并很快发布(示例数组不是确切的数组。)
【解决方案3】:

发现问题。数组的第 91 个元素实际上是数组的 reference。然后 foreach 使用相同的变量名(引用相同的数组 - 在我在问题中给出的示例 sn-p 中命名为 $unused),因此两者都在查看同一个数组。

在为你们发布后,我们注意到数组转储中的“&”,因此 StackOverflow 帮助了我们的调试过程......感谢大家的投入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 2021-08-03
    • 2013-01-15
    相关资源
    最近更新 更多