|   | php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
| 
  [2003-11-25 04:58 UTC] php dot net dot 1 at odi dot ch
 Description: ------------ The behaviour of foreach seems to be scope dependent. The following code (slightly more than 20 lines) should yield the same results in both cases, but doesn't. I know that foreach uses the internal array pointer. The result beeing "de" or "de fr it" is NOT the topic here. The point is that the two results differ, although the code is the same except for the scope. This could be the reason for bug #19285 Reproduce code: --------------- <?php $usr_langs = array('de', 'fr', 'it'); function f() { global $usr_langs; foreach($usr_langs as $lang) { # do something } } function g() { global $usr_langs; foreach ($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 "; } ?> Expected result: ---------------- Test1: de ---------- Test2: de OR even better Test1: de fr it ---------- Test2: de fr it Actual result: -------------- Test1: de ---------- Test2: de fr it PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             | |||||||||||||||||||||||||||||||||||||
|  Copyright © 2001-2025 The PHP Group All rights reserved. | Last updated: Fri Oct 31 01:00:01 2025 UTC | 
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 itHere'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.