Why does PHP overwrite values when I iterate through this array twice (by reference, by value)

前端 未结 3 371
灰色年华
灰色年华 2020-12-11 06:47

If I iterate through an array twice, once by reference and then by value, PHP will overwrite the last value in the array if I use the same variable name for each loop. This

相关标签:
3条回答
  • 2020-12-11 07:09

    After the first loop $element is still a reference to the last element/value of $array.
    You can see that when you use var_dump() instead of print_r()

    array(5) {
      [0]=>
      int(2)
    ...
      [4]=>
      &int(2)
    }
    

    Note that & in &int(2).
    With the second loop you assign values to $element. And since it's still a reference the value in the array is changed, too. Try it with

    foreach($array as $element)
    {
      var_dump($array);
    }
    

    as the second loop and you'll see.
    So it's more or less the same as

    $array = range(1,5);
    $element = &$array[4];
    $element = $array[3];
    // and $element = $array[4];
    echo $array[4];
    

    (only with loops and multiplication ...hey, I said "more or less" ;-))

    0 讨论(0)
  • 2020-12-11 07:15

    This is how you would fix this problem:

    foreach($array as &$element)
    {
        $element *= 2;
    }
    unset($element); #gets rid of the reference and cleans the var for re-use.
    
    foreach($array as $element) { }
    
    0 讨论(0)
  • 2020-12-11 07:28

    Here's an explanation from the man himself:

    $y = "some test";
    
    foreach ($myarray as $y) {
        print "$y\n";
    }
    

    Here $y is a symbol table entry referencing a string containing "some test". On the first iteration you essentially do:

    $y = $myarray[0];  // Not necessarily 0, just the 1st element
    

    So now the storage associated with $y is overwritten by the value from $myarray. If $y is associated with some other storage through a reference, that storage will be changed.

    Now let's say you do this:

    $myarray = array("Test");
    $a = "A string";
    $y = &$a;
    
    foreach ($myarray as $y) {
        print "$y\n";
    }
    

    Here $y is associated with the same storage as $a through a reference so when the first iteration does:

    $y = $myarray[0];
    

    The only place that "Test" string can go is into the storage associated with $y.

    0 讨论(0)
提交回复
热议问题