Assign by reference PHP misunderstaning

纵饮孤独 提交于 2019-12-10 20:22:59

问题


Whats the meaning of $arr[0] result "2" in the code given below, $arr2 is copying $arr and increasing its first value by one, so the result of $arr2[0] "2" is understaning,but whats happening with $arr, when i pass by reference $arr[0] to $a like so $a=&$arr[0] the result of $arr[0] is 2, when i pass it by value $a=$arr[0[ the result of $arr[0] would be set to 1 as it should, can anyone enlighten me on this?

<?php
$a = 1;
$arr = array(1);
$a = &$arr[0];
$arr2 = $arr;
$arr2[0]++;
echo $arr[0]. "<br>";//2
echo $arr2[0]. "<br>";//2
?>

回答1:


References in PHP are not like pointers; when you assign or pass something by reference, you create what we might call a "reference set" where both variables are references to the same "zval" (the structure in memory which holds the type and value of a variable).

An important consequence of this is that references are symmetrical. I tend to write assign by reference as $foo =& $bar rather than $foo = &$bar to emphasise this: the operator doesn't just take a reference to $bar and put it into $foo, it affects both operands.

With that in mind, let's go through your example:

$arr = array(1);

This will create two zvals: one for the array $arr itself, and one for the value in position 0 of that array ($arr[0]).

$a =& $arr[0];

This binds $a and $arr[0] into a reference set. Whichever of those names we use, we will be using the same zval that was previously created, and currently holds 1.

$arr2 = $arr;

This copies the contents of $arr into a new array zval, $arr2. But it doesn't resolve the references inside that array into values, it just copies the fact that they are a reference.

So $arr2[0] is now also part of the reference set containing $arr[0] and $a.

$arr2[0]++;

This increments the zval pointed to by our reference set, from 1 to 2.

echo $arr[0]. "<br>";//2
echo $arr2[0]. "<br>";//2

Since these are both part of the same reference set, they both point to the same zval, which is integer 2.


The inevitable question is, "bug or feature?" A more useful example would be passing an array containing references into a function:

function foo($array) {
   $array[0] = 42;
   $array[1] = 69;
}
$a = 1;
$b = 1;
$foo = [ &$a, &$b ];
foo($foo);
echo $a; // 42
echo $b; // 69

Like assignment, passing into the function didn't break the references, so code manipulating them can safely be re-factored into multiple functions.




回答2:


Not sure if this is a bug but var_dump() can help to explain.

<?php
$a = 1;
$arr = array(1);

var_dump( $arr );
$a = &$arr[0];
var_dump( $arr );

$arr2 = $arr;
$arr2[0]++;

Output:

array(1) {
  [0]=>
  int(1)
}

array(1) {
  [0]=>
  &int(1)
}

Take note of &int(1) in the second var_dump(). This tells us that position #0 of $arr has been turned into a reference pointer to a position in PHP's memory instead of remaining a dedicated value.

So when you perform $arr2 = $arr;, $arr2 receives that reference pointer as well.



来源:https://stackoverflow.com/questions/50951495/assign-by-reference-php-misunderstaning

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