문제

Could you explain, in short (because reading and understanding How does PHP 'foreach' actually work? takes a lot of time), why does this infinite loop:

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

whereas this does not:

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

nor does this

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

?

도움이 되었습니까?

해결책

The first array is iterated BY REFERENCE, as the second array. This is because iterated elements are referenced (&$v) and so the original array MUST be affected. If you extend the array variable, the same iterated array is extended infinitely.

For the second array is the same case, but the condition test to perform the next iteration was done beforehand, so it doesn't matter the array is extended by one, it's marked as terminated in that test.

The third array is iterated by value (and thus copied). PHP does that if no reference is needed to the array (or array values in the foreach loop; or the array itself is not a reference regarding it's zval). So extending the array will not alter the iterated array (since it's a copy and not the array in the variable).

More: (guess where?) Here

다른 팁

Your first loop, the infinite one, is updating the array WITHIN the loop. Every time you push a new element onto the end of the array with [], you're EXTENDING the array with a new element for the foreach to iterate over.

what's happening is:

  1. foreach initializes
  2. there's two elements, so process the first one
  3. since there's more elements left, the internal "continue the foreach" flag is set
  4. you push a new element onto the array (now there's 3)
  5. the foreach gets a new element off the array, and... there's STILL an element left (Your new #3), so the "continue the loop" flag stays set
  6. you push element #4 on, and so on.

With the other arrays, you're starting out with a SINGLE element

  1. foreach initializes
  2. there's one element, so process it
  3. there's no more elements after this first one, so "end the loop" flag gets set
  4. you push your new element
  5. the loop terminates, because the test for continuation was performed BEFORE you pushed the new element.

Essentially, you've strapped a carrot to a stick in front of PHP and it's just following behind the carrot.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top