php-general Digest 25 Mar 2012 16:02:19 -0000 Issue 7744
Topics (messages 317257 through 317259):
Re: foreach weirdness
317257 by: Arno Kuhl
317258 by: Arno Kuhl
Re: Thinking out loud - a continuation...
317259 by: Jay Blanchard
Administrivia:
To subscribe to the digest, e-mail:
php-general-digest-subscr...@lists.php.net
To unsubscribe from the digest, e-mail:
php-general-digest-unsubscr...@lists.php.net
To post to the list, e-mail:
php-gene...@lists.php.net
----------------------------------------------------------------------
--- Begin Message ---
> See this following example that illustrates 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
Hey,
the ouput you get is right. If you want your ouput you have to rewrite your
code.
Currently you are adding the value of the current index to the next indexes
value (e.g. $array[0] + $array[1]; $array[1] + $array[2]; etc.).
As I understand it you want to add the current value with the next index (e.g.
$array[0] + 1; $array[1] + 2; $array[2] + 3).
--
Hi Stephan, the first foreach loop adds the next value to the current value,
not the next index. The reason you don't get the expected result in the first
foreach loop is because you need to assign the $value by reference, as per the
php manual
foreach ($array as $index=>&$value)
But then to get the correct output from the second simple foreach loop, you
also have to assign the $value by reference, contrary to the php manual. If you
don't you get the wrong result and the array becomes corrupted. That could be
classified as a bug, or at least the manual needs to elaborate on using a
foreach when you assign the $value by reference.
Cheers
Arno
--- End Message ---
--- Begin Message ---
From: Simon Schick [mailto:simonsimc...@googlemail.com]
Sent: 24 March 2012 12:30 AM
To: Robert Cummings
Cc: a...@dotcontent.net; php-gene...@lists.php.net
Subject: Re: [PHP] foreach weirdness
2012/3/23 Robert Cummings <rob...@interjinn.com>
>
> On 12-03-23 11:16 AM, Arno Kuhl wrote:
>>
>>
>> it still does not produce the correct result:
>> 0 1 3 6 10 15 21
>> 0 1 3 6 10 15 15
>
>
> This looks like a bug... the last row should be the same. What version
> of PHP are you using? Have you checked the online bug reports?
>
>
Hi, Robert
Does not seem like a bug to me ...
http://schlueters.de/blog/archives/141-References-and-foreach.html
What you should do to get the expected result:
Unset the variable after you don't need this reference any longer.
Bye
Simon
--
Hi Simon, unsetting the $value does fix the problem, but I found that any time
you assign $value by reference in a foreach loop you have to do an unset to
avoid corrupting the array unless you continue to assign $value by reference
(as illustrated in the article you linked).
So doing something as simple as:
$array = array(0, 1, 2, 3, 4, 5, 6);
foreach ($array as $key=>&$value) {
echo "Key: $key; Value: $value<br />\n";
}
and then follow with (from the php manual):
foreach ($array as $key=>$value) {
echo "Key: $key; Value: $value<br />\n";
}
will not only give the wrong result, it will corrupt the array for *any*
further use of that array. I still think it’s a bug according to the definition
of foreach in the php manual. Maybe php needs to do an implicit unset at the
closing brace of the foreach where was an assign $value by reference, to remove
the reference to the last element (or whatever element it was pointing to if
there was a break) so that it doesn't corrupt the array, because any assign to
$value after the foreach loop is completed will corrupt the array (confirmed by
testing). The average user (like me) wouldn't think twice about reusing $value
after ending the foreach loop, not realising that without an unset the array
will be corrupted.
BTW thanks for that reference, it was quite an eye-opener on the pitfalls of
using assign by reference, not only in the foreach loop.
Cheers
Arno
--- End Message ---
--- Begin Message ---
[snip]
a necessary part of building the structure. It can be removed but only as a
post process. Why does it have to be removed? You can loop through the
structure in JavaScript without paying heed to the key's value.
>
> If it absolutely must go... you need to recurse through the final structure
> replacing each "children" entry with the results of passing it through
> array_values().
[/snip]
Unfortunately the user of the JSON will not make a change to their app. I have
looked through the JSON to confirm that this has a particular pattern so I
think I can just do a little regex and get it squared away. This is one of
"those" projects. It is apparently going to be trying every step of the way.
--- End Message ---