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

Reply via email to