php-general Digest 26 Mar 2012 06:39:23 -0000 Issue 7745

Topics (messages 317260 through 317262):

Re: foreach weirdness
        317260 by: Matijn Woudt
        317261 by: Simon Schick
        317262 by: Arno Kuhl

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 ---
On Sun, Mar 25, 2012 at 4:11 PM, Arno Kuhl <a...@dotcontent.net> wrote:
> 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

Note that somewhat similar error was discussed on this list a few
months ago[1]. You could probably have solved it yourself if you
searched the mailing list archives.

- Matijn

[1] http://www.mail-archive.com/php-general@lists.php.net/msg269552.html

--- End Message ---
--- Begin Message ---
2012/3/25 Arno Kuhl <a...@dotcontent.net>:
>
> 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.
>

Hi, Arno

Requesting that will at least require a major-release (f.e. PHP 6.0)
... but I would rather request to add a notice or warning to the
documentation of references to remind stuff like that.
http://www.php.net/manual/en/language.references.php
I think this is stuff more people will stumble over ...

Bye
Simon

--- End Message ---
--- Begin Message ---
Requesting that will at least require a major-release (f.e. PHP 6.0) ... but I 
would rather request to add a notice or warning to the documentation of 
references to remind stuff like that.
http://www.php.net/manual/en/language.references.php
I think this is stuff more people will stumble over ...

Bye
Simon
--

I agree it would be wrong to change php's handling of call by reference in 
foreach loops because there may be a need to access that reference after 
completing the loop. I was going to suggest there should be a warning in the 
manual to unset the reference after the foreach loop is completed, but I see 
the current online manual has that warning prominently displayed on the foreach 
page. I had a version of the manual from July last year that didn't have the 
warning, so I'll update my local manual and make sure I keep it up to date. 
Lesson learned (both manual and foreach references).

Cheers
Arno


--- End Message ---

Reply via email to