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

最后都变了- 提交于 2019-11-28 12:30:33

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" ;-))

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.

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) { }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!