Yasuo Ohgaki wrote on 16/01/2015 08:40:
Hi all,
Take a look at
http://3v4l.org/HbVnd
foreach should not affect internal(zval) array position, but it does.
I'm not sure why foreach works this way, but HHVM behavior is
reasonable. IMHO.
PHP 7 would be perfect opportunity fix this behavior.
Any comments?
I seem to remember somebody mentioning that the pointer is reused in
some situations and not others. I think the reason is efficiency - we
have a pointer associated with each array, which is rarely used, so why
not borrow it for foreach? (Answer: because it causes the oddity you
just spotted. :P)
For instance, if you put a reset() in the middle of the foreach loop, it
doesn't interrupt the progress of the loop, but does cause it to be
tracked separately and output "Apple" after the loop finishes:
http://3v4l.org/KTCrI
There are other weird cases, like nesting two foreach loops over the
same variable:
- with a true array, the loops are independent (both loops see the full
set of values): http://3v4l.org/lJTQG
- with a rewindable Traversable, such as SimpleXMLElement, they interact
(the inner loop sees all values, but the outer loop doesn't continue
after the inner one completes): http://3v4l.org/fs2Jv
- with a non-rewindable Traversable, such as a Generator, PHP tries to
rewind and gives a fatal error, while HHVM simply uses up the last
values of the generator on the inner loop (possibly a bug?):
http://3v4l.org/BYOmQ
My conclusion: don't try and nest foreach or any related constructs
using the same variable, because the behaviour is not guaranteed to be
in any way sane.
Regards,
--
Rowan Collins
[IMSoP]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php