foreach loop and reference of &$value

Why is an empty foreach loop can change the result.

I have the following code:

$variable = [1,2,3,4];
foreach ($variable  as $key => &$value) 
  $value ++;

var_dump($variable);

The result I get is:

array (size=4)
  0 => int 2
  1 => int 3
  2 => int 4
  3 => &int 5

Now, when I add an empty foreach loop like this:

$variable  = [1,2,3,4];
foreach ($variable  as $key => &$value) 
  $value ++;

foreach ($variable  as $key => $value);
  var_dump($variable);

I get this :

array (size=4)
  0 => int 2
  1 => int 3
  2 => int 4
  3 => &int 4

can someone explain me why the last element doesn't change when I add the second empty loop, and why there is a & infront of the last element?


At the end of the first loop, $value is pointing to the same place as $variable[3] ( they are pointing to the same location in memory ):

$variable  = [1,2,3,4];
foreach ($variable  as $key => &$value) 
    $value ++;

Even as this loop is finished, $value is still a reference that's pointing to the same location in memory as $variable[3] , so each time you store a value in $value , this also overwrites the value stored for $variable[3] :

foreach ($variable as $key => $value);
var_dump($variable);

With each evaluation of this foreach, both $value and $variable[3] are becoming equal to the value of the iterable item in $variable.

So in the 3rd iteration of the second loop, $value and $variable[3] become equal to 4 by reference, then during the 4th and final iteration of the second loop, nothing changes because you're passing the value of $variable[3] (which is still &$value ) to $value (which is still &$value ).

It's very confusing, but it's not even slightly idiosyncratic; it's the code executing exactly as it should.

More info here: PHP: Passing by Reference


This is a name collision: the name $value introduced in the first loop exists after it and is used in the second loop. So all assignments to it are in fact assignments to the original array. What you did is easier observed in this code:

  $variable = [1,2,3,4];
  foreach ($variable  as $key => &$value) 
    $value ++;
  $value = 123; // <= here you alter the array!
  var_dump($variable);

and you will see $variable[3] as 123 .

One way to avoid this is, as others said, to unset ($value) after the loop, which should be a good practice as recommended by the manual. Another way is to use another variable in the second loop:

  $variable  = [1,2,3,4];
  foreach ($variable  as $key => &$value) 
    $value ++;
  foreach ($variable  as $key => $val);
  var_dump($variable);

which does not alter your array.


The last element of the array will remian even after the foreach loop ..So its needed to use unset function outside the loop ..That is

$variable  = [1,2,3,4];
  foreach ($variable  as $key => &$value) {
$value++;


}
  unset($value);
  var_dump($variable); 

The link to the manual can be found here http://php.net/manual/en/control-structures.foreach.php

链接地址: http://www.djcxy.com/p/53040.html

上一篇: 在没有循环的数组中的N位置获取元素

下一篇: foreach循环和&$ value的引用