Re: Possible foreach bug; seeking advice to isolate the problem
| From: | Gary | Date: | Wed, 20 Oct 2010 06:37:55 +0000 |
| Subject: | Re: Possible foreach bug; seeking advice to isolate the problem | ||
| References: | 1 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-308877@lists.php.net to get a copy of this message | ||
Jonathan Sachs wrote:
> I've got a script which originally contained the following piece of
> code:
>
> foreach ( $objs as $obj ) {
> do_some_stuff($obj);
> }
>
> When I tested it, I found that on every iteration of the loop the last
> element of $objs was assigned the value of the current element.
I only had a few minutes to look at it, but here is my 2 Euro cents.
It only occurs when you have previously done
,----
| foreach ( $objs as &$obj ) {
| //anything or nothing here
| }
`----
as described in the documentation.
> That leaves me with the question: what is going wrong with foreach?
> I'm trying to either demonstrate that it's my error, not the PHP
> engine's, or isolate the problem in a small script that I can submit
> with a bug report.
From the post you reference in the manual's comments:
$a = array('a', 'b','c');
foreach($a as &$row){
//you don't have to do anything here
}
print_r($a);
foreach($a as $row){
echo "<br />".$row;
}
print_r($a);
This suffices.
> I tried to eliminate the database by doing a var_export of the array
> after I built it, then assigning the exported expression to a variable
> immediately before the foreach. That "broke the bug" -- the loop
> behaved correctly.
Yup. I guess whatever database code used previously was doing the
equivalent of the first foreach in the previous code snippet.
> Can anyone make suggestions on this -- either insights into what's
> wrong, or suggestions for producing a portable, reproducible example?
Better. I can tell you how to solve it:
$a = array('a', 'b','c');
foreach($a as &$row){
//you don't have to do anything here
}
unset($row); // <----<<< THIS IS KEY!
print_r($a);
foreach($a as $row){
echo "<br />".$row;
}
print_r($a);
I admit though, it's not obvious, even from reading the manual, and is
definitely a bug in the sense it is unexpected behaviour. Documenting it
and calling it a "feature" is appalling.