foreach中的无限循环取决于数组初始化

时间:2014-04-23 17:05:05

标签: php arrays foreach initialization infinite-loop

简而言之,你可以解释一下(因为阅读和理解 How does PHP 'foreach' actually work? 需要花费很多时间),为什么会出现这种无限循环:

$foo = array(0, 1); foreach($foo as &$v) $foo[] = 42;

而这不是:

$foo = array(0); // 1 element at initialization foreach($foo as &$v) $foo[] = 42;

也不是这个

$foo = array(0, 1); foreach($foo as $v) // not using a ref as foreach iterator $foo[] = 42;

2 个答案:

答案 0 :(得分:1)

你的第一个循环,无限循环,是在循环中更新数组。每次使用[]将新元素推送到数组的末尾时,您将使用新元素扩展数组,以便foreach迭代。

发生的事情是:

  1. foreach初始化
  2. 有两个元素,所以处理第一个元素
  3. 因为还剩下更多元素,所以设置内部“继续foreach”标志
  4. 你将一个新元素推送到数组(现在有3个)
  5. foreach从数组中获取一个新元素,并且......仍然有一个元素(你的新#3),所以“继续循环”标志保持不变
  6. 你按下元素#4,依此类推。
  7. 使用其他数组,您将开始使用SINGLE元素

    1. foreach初始化
    2. 有一个元素,所以处理它
    3. 在第一个之后没有其他元素,所以“结束循环”标志设置
    4. 你推新元素
    5. 循环终止,因为在推送新元素之前执行了继续测试。
    6. 基本上,你已经在PHP面前将一根胡萝卜绑在棍子上了,它只是在胡萝卜后面。

答案 1 :(得分:1)

第一个数组是BY REFERENCE,作为第二个数组。这是因为引用了迭代元素(& $ v),因此原始数组必须受到影响。如果扩展数组变量,则无限扩展相同的迭代数组。

对于第二个数组是相同的情况,但是执行下一次迭代的条件测试是事先完成的,所以数组扩展为1无关紧要,它在该测试中被标记为终止。

第三个数组按值迭代(因此被复制)。如果数组不需要引用(或foreach循环中的数组值;或者数组本身不是关于它的zval的引用),PHP就会这样做。因此扩展数组不会改变迭代数组(因为它是副本而不是变量中的数组)。

更多:(猜哪里?)Here