Foreach behavior with variables by reference

Asked

Viewed 377 times

3

I was doing some tests and I realized that the foreach has a strange behavior.

Suppose I have the following array:

$array = array('primeiro', 'segundo', 'terceiro');

When I run one foreach using a reference, and then another without reference foreach (with the same variable), see what happens:

$array = array('primeiro', 'segundo', 'terceiro');

foreach ($array as &$b);

var_dump($array);

foreach ($array as $b);

var_dump($array);

Upshot:

array (size=3)
  0 => string 'primeiro' (length=8)
  1 => string 'segundo' (length=7)
  2 => &string 'terceiro' (length=8)

array (size=3)
  0 => string 'primeiro' (length=8)
  1 => string 'segundo' (length=7)
  2 => &string 'segundo' (length=7)

See that the last element has a different value.

Then two questions arose:

  • The last value of $array has become the penultimate element?
  • Why, after a foreach with variable by reference, the last element is as referenced by the variable (which is after the as)?

Observing: Repair the sign of & in the result.

  • 4

    There’s a nice discussion at the SO gringo about it here

  • 1

    To ask a creative question when the goal, it seems to me, is the very construction of the question, is really difficult. Questions that come from real problems that people encounter, in general, are much more productive and well accepted by the community.

1 answer

5


When you "equal" two variables, you can do this in two ways:

  • By value: Indicating that at that point in the code the value of one is equal to that of the other:

    $a = $b;
    
  • By reference: Indicating that, until it is said otherwise, they are equal, that is, what happens to one should happen to the other:

    $b = "b";
    $a = &$b;
    var_dump($a);   //Imprime: var 'b'
    
    $a = 'a';
    var_dump($b);   //Imprime: var 'a'
    

When passing the variable $b by reference in the first foreach, you are, at each iteration, linking the value of $b with a vector position $array.

$b = &$array[0];  //na primeira iterada 

When establishing the link with another variable, the first link is broken, that is, in the second iteration $b is linked with $arrray[1] and no longer with $array[0]. In other words, at the end of the first foreach, $b is linked to (and only to) the third position of the vector:

$b = &$array[2];  //na última iterada

In the second foreach, with each iteration, we are saying that $b has a new value and therefore, $arrray[2] also has a new value with each iteration. In the penultimate iteration we do:

$b = $array[1];
//o que implica que também estamos fazendo $array[2] = $array[1];

And therefore, when we arrive at the last iteration of the second foreach, the last position is with the value of the penultimate.

  • 1

    understood. Just to supplement the question: for this not to happen in the second foreach, we should simply make a unset($b)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.