Bug #70812 [Nab]: Nested foreach with iterators

From: Date: Thu, 29 Oct 2015 17:09:01 +0000
Subject: Bug #70812 [Nab]: Nested foreach with iterators
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-196882@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=70812&edit=1 ID: 70812 User updated by: fra dot casula at gmail dot com Reported by: fra dot casula at gmail dot com Summary: Nested foreach with iterators Status: Not a bug Type: Bug Package: *General Issues Operating System: Ubuntu 15.10 x64 PHP Version: 5.6.14 Block user comment: N Private report: N New Comment: I get what you're saying, arrays are by value. Objects, starting from PHP5, are by reference. Still if I unset an element of the same array in the nested foreach I get that element wiped in the main array as well. $a = [1, 2, 3, 4]; foreach ($a as $i => $v) { foreach ($a as $i2 => $v2) { if ($i2 % 2 == 0) { unset($a[$i2]); } } } var_dump($a); // it prints 2, 4 (of course) If each foreach is working with its own array copy like you said then there's probably a scope issue? The whole thing is confusing because someone would think that iterators work just like a normal array but then, even if we don't implement a thing and use the ready-to-use ArrayIterator class, we get a completely different behaviour with a simple thing like a nested foreach. It's not just a completely different behaviour, it's just unreliable. The ArrayIterator class, as it is, can't even be used in a nested foreach unless we start setting positions manually. That would probably make us loose the benefit of using iterators in the first instance. Previous Comments: ------------------------------------------------------------------------ [2015-10-29 15:41:21] bwoebi@php.net The difference is that arrays are by-value — they have all own copies which are all individually iterated. [At least that's how they function semantically.] Iterators though are objects and thus share a common state. It's not like arrays would be seeking each time and iterators not. Just each foreach works on its own array copy, but shares the object. ------------------------------------------------------------------------ [2015-10-29 13:49:41] fra dot casula at gmail dot com Description: ------------ A nested foreach on the same iterator doesn't produce the same result that is produced when using plain arrays. The nested foreach should call seek() to reset the internal pointer to its correct position so that the first foreach can resume where it stopped. Test script: --------------- http://pastebin.com/EQrUZ7AQ Expected result: ---------------- I expect to see the same output for all four cases in the example code. The expected output is: first loop 0 second loop 0 second loop 1 second loop 2 first loop 1 second loop 0 second loop 1 second loop 2 first loop 2 second loop 0 second loop 1 second loop 2 Actual result: -------------- first loop 0 second loop 0 second loop 1 second loop 2 ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=70812&edit=1

« previous php.bugs (#196882) next »