Debugging a foreach loop |
Site Admin
|
Everything is okay with debugger
and $array[2] is 1, not 7 -- the beginning. I'd recommend to check your code one more time. As soon as $index gets 1, your code copies value at the 1st index to the 2nd (and so forth). Probably it's what you didn't take into account. |
||||||||||||
_________________ The PHP IDE team |
|
Definitely nothing wrong with the debugger. I think the confusion is why $value is not the same as $array[$index] when the array value was changed during the previous iteration - the reason is that foreach is working on a copy of the array, not the actual array itself. So if you change the contents of the array while looping through it, it won't affect the copy of the array that your looping through. So, for example, during the iteration with an $index of 1, when $array[2] ($array[$index+1]) is changed from 1 to 7, when the foreach loops gets to the next iteration ($index of 2), $value will still be 1 (instead of the new value of 7). To make $value and $array[$index] the same, you would have to assign $value by reference, and then both $value and $array[$index] would always be the same.
Example with $value as reference: $array = array(4, 7, 1, 5, 0, 12, 9); // make sure each value is greater than or equal to the preceding value // This example assigns $value by reference - $array[$index] and $value will be identical foreach ($array as $index=>&$value) { if ( ($index+1) == count($array) ) break; if ($array[$index] > $array[$index+1]) { $array[$index+1] = $array[$index]; } } |
||||||||||||
|
|
Thanks ldemon, that answers my question. And I can see it's not a debugger issue but rather a php issue. However I made a change to the example and I'm still rather baffled.
I originally used a bad example because it always worked after leaving the foreach loop, though my actual code was quite different. I think this example is a better illustration of the problem: $array = array(0, 1, 2, 3, 4, 5, 6); foreach ($array as $index=>$value) { if ( ($index+1) < count($array) ) { $array[$index+1] += $value; } echo $value." "; } echo "<br />"; foreach ($array as $index=>$value) { echo $value." "; } You'd expect the output to be: 0 1 3 6 10 15 21 0 1 3 6 10 15 21 But it's actually: 0 1 2 3 4 5 6 0 1 3 5 7 9 11 Now if I change the code to assign the $value by reference as you rightly suggested: $array = array(0, 1, 2, 3, 4, 5, 6); foreach ($array as $index=>&$value) { if ( ($index+1) < count($array) ) { $array[$index+1] += $value; } echo $value." "; } echo "<br />"; foreach ($array as $index=>$value) { $dummy = 1; // added for the debugger echo $value." "; } it still does not produce the correct result: 0 1 3 6 10 15 21 0 1 3 6 10 15 15 If I watch the $array I see odd behavior for the last element $array[6] when stepping through the second foreach loop. Just before entering the second loop $array[6] == 21 which is correct. When I press F8 to get to the next line $array[6] == 0 !! As I step through the loop $array[6] keeps on changing for each iteration, with the following values: 0, 1, 3, 6, 10, 15, 15 And once I've left the second loop $array[6] is permanently changed from 21 to 15, even though there is no code in the second loop to change $array[6]. So what is going on here? BTW I agree this is not a debugger issue because if I change the code to: $array = array(0, 1, 2, 3, 4, 5, 6); foreach ($array as $index=>&$value) { if ( ($index+1) < count($array) ) { $array[$index+1] += $value; } echo $value." "; } echo "<br />"; foreach ($array as $index=>$value) { $dummy = 1; // added for the debugger echo $array[6]." "; } echo "<br />"; echo $array[6]; the result is: 0 1 3 6 10 15 21 0 1 3 6 10 15 15 15 And if I change the code to: $array = array(0, 1, 2, 3, 4, 5, 6); foreach ($array as $index=>&$value) { if ( ($index+1) < count($array) ) { $array[$index+1] += $value; } echo $value." "; } echo "<br />"; foreach ($array as $index=>&$value) { $dummy = 1; // added for the debugger echo $array[6]." "; } echo "<br />"; echo $array[6]; I finally get the correct result: 0 1 3 6 10 15 21 21 21 21 21 21 21 21 21 Have I really been using the foreach loop incorrectly for all these years? I always seemed to get the expected result up till now. The following snippet is copied directly from the php manual: foreach ($arr as $key => $value) { echo "Key: $key; Value: $value<br />\n"; } But the above example seems to indicate this isn't correct. Still confused. |
||||||||||||
|
Site Admin
|
Look, it's very good that you're learning php here (I'm serious because I know that php can bring surprises time after time)
But I'm sorry to say that it's a bit out of scope of this forum. Most likely you want to ask your questions at php.general and php.internals newsgroup http://www.php.net/mailing-lists.php btw, unexpected behaviour of foreach was discussed there multiple times. As of debugger or phped, your questions are welcome if you think that debugger works wrong or unclear. In this case, you have to provide some info on what works differently with debugger than without it. |
||||||||||||
_________________ The PHP IDE team |
|
Hi Dmitri, I originally thought it was a debugger problem, but as I clearly stated I realised it's not a debugger problem. I was merely (in a very long way) elaborating on the original problem that made me think it was a debugger problem, and was hoping some gurus here could shed some light on the issue. I have taken it up on the php forum. Didn't know the foreach problem had been discussed multiple times, though I've been on the php mailing list for many years.
|
||||||||||||
|
Site Admin
|
for example, try to find "bug when using foreach with references?" subject in php.internals newsgroup. There are also some other discussions about foreach happened during all the years since the server started. Also I remember it was reported as error multiple times at bugs.php.net...
Regarding debugger - if you and anybody else believe they found an error, it's very simple to check - just comment off debugger and try the same code without it. If it works differently, you may want to contact our support and ask for help. BTW, according to our history -- in most cases, it's Watch window with some forgotten function/method calls. You know you can call functions and methods here and they will certainly be called multiple times during debugging process. This may change the way your application works. Last time just 3 weeks ago one customer submitted report explaining that debugger would output "1" upon each stop in the debugger ... Guess what it was. |
||||||||||||
_________________ The PHP IDE team |
Debugging a foreach loop |
|
||
Content © NuSphere Corp., PHP IDE team
Powered by phpBB © phpBB Group, Design by phpBBStyles.com | Styles Database.
Powered by
Powered by phpBB © phpBB Group, Design by phpBBStyles.com | Styles Database.
Powered by