Re: Fixing strange foreach behavior.

From: Date: Fri, 16 Jan 2015 16:22:05 +0000
Subject: Re: Fixing strange foreach behavior.
References: 1  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
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]

Thread (12 messages)

« previous php.internals (#80648) next »