#26396 [Com]: foreach scope modality
| From: | jpatrin at pnicorp dot com | Date: | Tue, 25 Nov 2003 23:11:31 +0000 |
| Subject: | #26396 [Com]: foreach scope modality | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-51072@lists.php.net to get a copy of this message | ||
ID: 26396
Comment by: jpatrin at pnicorp dot com
Reported By: php dot net dot 1 at odi dot ch
Status: Wont fix
Bug Type: Arrays related
Operating System: *
PHP Version: 4.3.3
New Comment:
Ok, I'll accept that response, but why does foreach not make a copy of
the referenced array? I see no place in the foreach docs that say that
it doesn't make a copy when the variable is a reference.
Sidenote: I thought that all PHP vars were refernces and that usinf =&
made it a refernce to the same object instead of a refernce to a copy
of the object. If this is true, the copy should still be made just
fine. foreach is ALWAYS supposed to make a copy of the array and
foreach over that.
Previous Comments:
------------------------------------------------------------------------
[2003-11-25 17:21:46] helly@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
I was right then. Global creates a reference and referenced arrays
cannot be nested. When an array is passed to foreach and it is not a
reference then a copy of the array is created. That's where the
difference comes from.
------------------------------------------------------------------------
[2003-11-25 16:27:47] jpatrin at pnicorp dot com
Here's a bit more. If you use
$usr_langs =& $GLOBALS['usr_langs'];
instead of
global $usr_langs;
the same bug presents it self.
Also, if you put
global $usr_langs;
above the echo "Test2..." You get only "de" in the output. It seems
like global is munging the scope of foreach copies.
------------------------------------------------------------------------
[2003-11-25 16:08:19] helly@php.net
Interesting, anybody?
------------------------------------------------------------------------
[2003-11-25 13:22:18] jpatrin at pnicorp dot com
Here's the proof that the global keyword is broken. If you change the
code to use $GLOBALS as such:
<?php
function f() {
foreach($GLOBALS['usr_langs'] as $lang) {
}
}
function g() {
foreach($GLOBALS['usr_langs'] as $lang) {
f();
echo $lang.' ';
}
}
echo 'Test1:<br>';
g();
echo '<br>----------<br>';
echo 'Test2:<br>';
foreach($usr_langs as $lang) {
f();
echo $lang.' ';
}
?>
The output is:
Test1:
de fr it
----------
Test2:
de fr it
As was originally expected. Please either open this bug again or
explain why global is treated differently than $GLOBALS.
------------------------------------------------------------------------
[2003-11-25 13:12:37] jpatrin at pnicorp dot com
You *CAN* nest foreach loops, as I have been doing it for a LONG time.
You can even nest foreach loops with the same array and the output will
be as expected (see code at bottom). Because foreach works on a copy of
the array, it does not change the internal pointer and therefore there
are two bugs here. The first being that the outputs aren't the same and
second being that all values int he array are not output by g().
What seems to be happening if that f() is somehow altering the internal
pointer of the *copy* that g() is operating on. Is it almost certain
that this is a problem with how global is implemented.
This code:
<?php
foreach($usr_langs as $lang) {
echo "1 $lang<br/>";
foreach($usr_langs as $lang2) {
echo "2 $lang2<br/>";
}
}
?>
Produces this output:
1 de
2 de
2 fr
2 it
1 fr
2 de
2 fr
2 it
1 it
2 de
2 fr
2 it
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/26396
--
Edit this bug report at http://bugs.php.net/?id=26396&edit=1