Re: [PHP] Using next() inside a foreach



Erik Stackhouse wrote:
Hello,

I'm hesitant to report this issue as a bug, since I see other bugs
(43890 and 43220) already opened describing similar, but not identical,
issues. The latter bug is described as a documentation issue...

In my tests all versions of php prior to 5.2.4, foreach does NOT
increment the array pointer for each iteration, at least not at the top
of the loop. This new behavior in 5.2.4 breaks array look-ahead logic,
when using next() -- since you end up looking TWO places ahead instead
of one.

This produces the effect that in the body of the loop, current()
actually returns the "next" value in the array -- which is the
workaround I've implemented in my code for doing a look-ahead -- though
it seems non-intuitive to have current() return the next value.

Perhaps the previous behavior was to increment the array pointer at the
END of the foreach block, and now for some reason it's incrementing it
at the BEGINNING? That would explain it I guess...

Perhaps there's a better way to do look-ahead, but for a behavior change
like this, if it's intentional, shouldn't it at least be in the
"Backward Compatibility" section of the migration docs?


Check out the second NOTE on the foreach page:

http://us2.php.net/foreach

Note: Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer. Don't rely on the array pointer during or after the foreach without resetting it.


if you are running next() or current() on the $test_arr below, you are not accessing the same array that is being used in the foreach loop. Foreach is using a copy of the $test_arr array().


Example Code:

$test_arr = array('zero', 'one','two','three','four');

foreach ($test_arr as $idx => $val) {

$next_val = next($test_arr);

print "This: " . $idx . " -> " . $val . "\n";
print "Next: " . $next_val . "\n";

}

---------------------------------------------
output under v5.2.3 (and 4.4.8):
---------------------------------------------

This: 0 -> zero
Next: one
This: 1 -> one
Next: two
This: 2 -> two
Next: three
This: 3 -> three
Next: four
This: 4 -> four
Next:

-------------------------------
output under v5.2.4 and v5.2.5:
-------------------------------

This: 0 -> zero
Next: two
This: 1 -> one
Next: three
This: 2 -> two
Next: four
This: 3 -> three
Next:
This: 4 -> four
Next:

-------------------------------

Regards to All,

-Erik



--
Jim Lucas

"Some men are born to greatness, some achieve greatness,
and some have greatness thrust upon them."

Twelfth Night, Act II, Scene V
by William Shakespeare
.



Relevant Pages

  • Re: [PHP] foreach() using current() strange beahvior
    ... that's expected as foreach moves the internal array pointer, ... When using the internal pointer just by calling current(so not moving ... Unless the array is referenced, foreach operates on a copy of the ...
    (php.general)
  • Re: a question about for and foreach
    ... foreach (@array) { ... why @array are changed after this foreach loop!!! ... The "foreach" loop iterates over a normal list value and sets the ... If any element of LIST is an lvalue, you can modify it by modifying ...
    (perl.beginners)
  • Re: safe to delete elements of array in foreach
    ... I agree with Jon on this one. ... I make it a habit not to delete entries in a foreach() loop. ... build an array of keys I want to delete, and after the loop ends, delete ... I don't know whether an operation like this is guaranteed to work in PHP ...
    (comp.lang.php)
  • Re: [PHP] Foreach
    ... The problem I am having is getting both to update the table in MySQL. ... echo "$t"; ... foreach { ... // foreach expects an array, ...
    (php.general)
  • Re: safe to delete elements of array in foreach
    ... (normally this is not the case but not sure in php) ... I make it a habit not to delete entries in a foreach() loop. ... build an array of keys I want to delete, and after the loop ends, ...
    (comp.lang.php)