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

 ID:                 60450
 User updated by:    developer at elementica dot com
 Reported by:        developer at elementica dot com
 Summary:            Looping in a copy of an array using foreach
                     by-reference change original array
 Status:             Bogus
 Type:               Bug
 Package:            Arrays related
 Operating System:   Linux, Windows
 PHP Version:        5.3.8
 Block user comment: N
 Private report:     N

 New Comment:

...and moreover:

if I use "$elem1" in the first loop and "$elem2" in the second it's buggy 
anyway!!


Previous Comments:
------------------------------------------------------------------------
[2011-12-06 10:55:23] developer at elementica dot com

I knew the trick. But I think that's just a trick (thankx very much, anyway!)

Foreach takes two arguments, the second being the iteration variable that 
should have a scope relative to the loop. This could also be seen as a feature, 
but we also find stated that "Referencing $value is only possible if the 
iterated array can be referenced (i.e. if it is a variable)".

So:
- if it's to be seen as a feature the latter shouldn't be true
- if it isn't (as it seems better) unset shouldn't be necessary

Let's have a different example...

Considering a function we could have:

function fun(&$x) {
  $x++;
};
$var1 = 7; // this is like the $array1 assignment
fun($var1); // this is like the foreach loop for $array1 (*)
$var2 = $var1; // this is like the $array2=$array1 assignment
fun($var2); // this is like the foreach loop for $array2 (*)
print_r($var1); // WE FIND 8

If we look at "fun" as "foreach" it seems to me we're in a similar case, but 
here $var1 isn't affected by the change of $var2.
(*) just like before... we're applying a construct (foreach before, a function 
now) to a referenced variable.

$x is just a formal parameter, just like $elem


I think the point is here... is $elem a formal parameter or not? I think yes 
would be a better answer.

------------------------------------------------------------------------
[2011-12-06 10:13:36] cataphr...@php.net

See 
http://nl.php.net/manual/en/language.references.whatdo.php#language.references.whatdo.assign
 near the end.

The work-around is unsetting the $elem variable after the last iteration when 
iterating by reference.

------------------------------------------------------------------------
[2011-12-06 10:05:23] developer at elementica dot com

Description:
------------
On a standard installation of PHP 5.3.x on many OSs (including Linux and 
Windows) we:
- set an array with at least two elements
- loop it using foreach by-reference changing each element
- create a copy of the array in another one using the "=" assignment
- loop on the copy as before
- we find the original array changed (usually or always: last element)

Example code given.

Documentation says "Array assignment always involves value copying. Use the 
reference operator to copy an array by reference." 

(http://php.net/manual/en/language.types.array.php).

It seems a problem of "foreach" used with the "by-reference" syntax.

Could be related to https://bugs.php.net/bug.php?id=8130 (subject appears to be 
the same, but here we have a foreach problem, while nothing is stated in #8130 
about it).

Test script:
---------------
$array1 = array(0 => 'zero', 1 => 'one');
foreach ($array1 as &$elem) { $elem .= ' (1)'; }; // NOTE: if we use $array1[0] 
.= ' (1)'; $array1[1] .= ' (1)'; no problem arises
$array2 = $array1;
foreach ($array2 as &$elem) { $elem .= ' (2)'; }; // NOTE: if we use $array2[0] 
.= ' (1)'; $array2[1] .= ' (1)'; the problem is still here, so first foreach 
seems to be the point
print_r ($array1);
// BUG! EXPECTED: array(0 => 'zero (1)', 1 => 'one (1)'), OUTPUT: array(0 => 
'zero (1)', 1 => 'one (1) (2)')

Expected result:
----------------
Array
(
    [0] => zero (1)
    [1] => one (1)
)

Actual result:
--------------
Array
(
    [0] => zero (1)
    [1] => one (1) (2)
)


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



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

Reply via email to