Bug #76231 [Csd->Nab]: while (list(x,y)=each(z)) fails after first loop
| From: | requinix@php.net | Date: | Wed, 18 Apr 2018 00:56:45 +0000 |
| Subject: | Bug #76231 [Csd->Nab]: while (list(x,y)=each(z)) fails after first loop | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-214786@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=76231&edit=1
ID: 76231
Updated by: requinix@php.net
Reported by: bmrgar at twc dot com
Summary: while (list(x,y)=each(z)) fails after first loop
-Status: Closed
+Status: Not a bug
Type: Bug
Package: Arrays related
Operating System: Linux
PHP Version: 7.2.4
Block user comment: N
Private report: N
New Comment:
> For what it's worth, a while context should have it's own scoped iterator.
while loops are not iterators. They are syntactic sugar around goto statements. So is foreach for
that matter, but it has a bit more sugar sprinkled in.
"Expected behavior" depends on how much one knows. In this case you weren't aware of
some important details.
Previous Comments:
------------------------------------------------------------------------
[2018-04-18 00:48:25] bmrgar at twc dot com
Ok - was still digging on this issue when I found the 'reset' array function. I've
closed this as I'm guessing the devs will say 'working as intended' due to that
function.
For what it's worth, a while context should have it's own scoped iterator. Otherwise,
loops that are 'for each' do not behave as expected (i.e. actually iterating *each*
element on specific runs, instead iterating of iterating none).
------------------------------------------------------------------------
[2018-04-18 00:45:36] requinix@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to
report
a bug at http://bugs.php.net/how-to-report.php
If you are going to iterate over an array manually then you must use the correct procedure. The
simplest form is
for (reset($array); key($array) !== null; next($array)) {
$key = key($array);
$value = current($array);
...
}
each() is deprecated so avoid using it.
Your problem is you are missing the reset(), which moves the internal pointer used by
key/current/next/etc. back to the beginning of the array. Creating a copy gives you a fresh version
with its pointer already at the beginning.
Or be normal and use a foreach.
------------------------------------------------------------------------
[2018-04-18 00:34:00] bmrgar at twc dot com
Description:
------------
After iterating through a key,value array with a while loop, subsequent loops through the same data
fail.
Directly accessing array elements still works, as does cloning the array and looping through the new
one (which will also fail after the first loop).
Test script:
---------------
$a = array("a"=>1,"b"=>2,"c"=>3);
print "\"a\" = ".$a["a"]."\n";
print "\"b\" = ".$a["b"]."\n";
print "\"c\" = ".$a["c"]."\n\n";
print "First loop:\n";
while (list($key,$value) = each($a)) { print "Key: \"$key\" = Value: $value\n";
} print "\n";
print "Second loop:\n";
while (list($key,$value) = each($a)) { print "Key: \"$key\" = Value: $value\n";
} print "\n";
print "Third loop (after copy of 'a' to 'b':\n";
$b = $a;
while (list($key,$value) = each($b)) { print "Key: \"$key\" = Value: $value\n";
} print "\n";
Expected result:
----------------
"a" = 1
"b" = 2
"c" = 3
First loop:
Key: "a" = Value: 1
Key: "b" = Value: 2
Key: "c" = Value: 3
Second loop:
Key: "a" = Value: 1
Key: "b" = Value: 2
Key: "c" = Value: 3
Third loop (after copy of 'a' to 'b':
Key: "a" = Value: 1
Key: "b" = Value: 2
Key: "c" = Value: 3
Actual result:
--------------
"a" = 1
"b" = 2
"c" = 3
First loop:
Key: "a" = Value: 1
Key: "b" = Value: 2
Key: "c" = Value: 3
Second loop:
Third loop (after copy of 'a' to 'b':
Key: "a" = Value: 1
Key: "b" = Value: 2
Key: "c" = Value: 3
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=76231&edit=1