Bug #53780 [Opn->Bgs]: Iterating twice over an array changes the array
| From: | cataphract@php.net | Date: | Tue, 18 Jan 2011 17:56:39 +0000 |
| Subject: | Bug #53780 [Opn->Bgs]: Iterating twice over an array changes the array | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-157987@lists.php.net to get a copy of this message | ||
Edit report at http://bugs.php.net/bug.php?id=53780&edit=1
ID: 53780
Updated by: cataphract@php.net
Reported by: daniel dot seif at castex dot de
Summary: Iterating twice over an array changes the array
-Status: Open
+Status: Bogus
Type: Bug
Package: *General Issues
Operating System: Ubuntu 11.04
PHP Version: 5.3.5
Block user comment: N
Private report: N
New Comment:
This is not a bug, it's an unfortunate consequence of the nonexistence
of block-scoped variables in PHP.
When the first foreach loop ends, $value will still exist and the last
element of $arr will be in the same reference set.
When the second foreach loop is running, $value will be written on each
iteration; when that happens, the last element of the array, which is in
the same reference set, will be changed too. From here, we can see that
the last of such assignments to have any effect is the penultimate,
since in the last assignment an element of the reference set is written
onto another such element, so it has no effect.
Previous Comments:
------------------------------------------------------------------------
[2011-01-18 17:06:45] daniel dot seif at castex dot de
Description:
------------
When using foreach to iterate over an array using the reference
(&$value) syntax, and using foreach a second time using the same
variable name changes the original array by overwriting the array's last
item with the second-last.
This is obviously wrong...
Hint: note the missing object's id #4 in the actual result
Test script:
---------------
// the example uses objects to show the object's id in the output, but
this error also occurs works with scalars
class A {}
$c = array(new A(), new A(), new A(), new A());
$arr = $c; // to keep the reference
var_dump($arr);
foreach ($arr as &$value) {}
var_dump($arr);
// using the same variable name
foreach ($arr as $value) {}
var_dump($arr);
Expected result:
----------------
array(4) {
[0]=>
object(A)#1 (0) {
}
[1]=>
object(A)#2 (0) {
}
[2]=>
object(A)#3 (0) {
}
[3]=>
object(A)#4 (0) {
}
}
array(4) {
[0]=>
object(A)#1 (0) {
}
[1]=>
object(A)#2 (0) {
}
[2]=>
object(A)#3 (0) {
}
[3]=>
object(A)#4 (0) {
}
}
array(4) {
[0]=>
object(A)#1 (0) {
}
[1]=>
object(A)#2 (0) {
}
[2]=>
object(A)#3 (0) {
}
[3]=>
object(A)#4 (0) {
}
}
Actual result:
--------------
array(4) {
[0]=>
object(A)#1 (0) {
}
[1]=>
object(A)#2 (0) {
}
[2]=>
object(A)#3 (0) {
}
[3]=>
object(A)#4 (0) {
}
}
array(4) {
[0]=>
object(A)#1 (0) {
}
[1]=>
object(A)#2 (0) {
}
[2]=>
object(A)#3 (0) {
}
[3]=>
&object(A)#4 (0) {
}
}
array(4) {
[0]=>
object(A)#1 (0) {
}
[1]=>
object(A)#2 (0) {
}
[2]=>
object(A)#3 (0) {
}
[3]=>
&object(A)#3 (0) {
}
}
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/bug.php?id=53780&edit=1