Bug #60534 [Com]: Iterating an array twice w and w/o references changes last item to second last

From: Date: Fri, 28 Aug 2020 03:32:43 +0000
Subject: Bug #60534 [Com]: Iterating an array twice w and w/o references changes last item to second last
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-228773@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=60534&edit=1

 ID:                 60534
 Comment by:         supplier at enex dot net
 Reported by:        aron dot cederholm at gmail dot com
 Summary:            Iterating an array twice w and w/o references
                     changes last item to second last
 Status:             Duplicate
 Type:               Bug
 Package:            Arrays related
 Operating System:   Arch Linux
 PHP Version:        5.3.8
 Block user comment: N
 Private report:     N

 New Comment:

Can anyone please provide an example of how this unusual behaviour might be useful? Having pulled my
hair out (like many others no doubt) it seems odd that this behaviour persists unless there is an
obvious point to it (other than to separate the super-geeks from the lesser-geeks) For super-geeking
there is always the standard for loop, so if there is a reason to punish us lesser geeks with this
foreach quirk please advise what the use-case is. 

thanks a million!


Previous Comments:
------------------------------------------------------------------------
[2011-12-15 17:09:50] anon at anon dot anon

This gets submitted as a bug about twice a month. It's still not a bug.

After the first loop finishes $a is a reference to the last element of the array. That means that
during the second loop, the last value of the array is constantly being modified by the loop. Once
it gets to the last element, 'd' has been overwritten already.

foreach ($array as &$a) {
	echo "($a): " . join(',', $array) . "\n";
}
foreach ($array as $a) {
	echo "($a): " . join(',', $array) . "\n";
}

(a): a,b,c,d
(b): a,b,c,d
(c): a,b,c,d
(d): a,b,c,d
(a): a,b,c,a
(b): a,b,c,b
(c): a,b,c,c
(c): a,b,c,c

As it says in the manual, unset() after foreach'ing by reference: http://www.php.net/manual/en/control-structures.foreach.php

------------------------------------------------------------------------
[2011-12-15 15:15:12] aron dot cederholm at gmail dot com

Description:
------------
Iterating an array twice, first time with references, second time *without* 
references, will trigger a bug in the second iteration where the last item of the 
array is overwritten by the second last item in the array. This seem to be the 
same bug as #46123, which was dismissed on erroneous grounds




Test script:
---------------
<?
# For a more verbose look at this bug, watch http://pastebin.com/gq2qekYh

$array = array('a', 'b', 'c', 'd'); # testing array
foreach ($array as &$a) {}
foreach ($array as $a) {}
echo join(',', $array); # will produce a,b,c,c *not* a,b,c,d as expected
die();

## while, these will work as expected

# 1
foreach ($array as $a) {}
print_r($array);
die();

# 2
foreach ($array as &$a) {}
print_r($array);
die();

# 3
foreach ($array as &$a) {}
foreach ($array as &$a) {}
print_r($array);
die();

# 4
foreach ($array as $a) {}
foreach ($array as $a) {}
print_r($array);
die();

# 5
foreach ($array as $a) {}
foreach ($array as &$a) {}
print_r($array);
die();

?>

Expected result:
----------------
a,b,c,d

Actual result:
--------------
a,b,c,c


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=60534&edit=1


Thread (6 messages)

« previous php.bugs (#228773) next »