$ arr [0]结果“ 2”的含义在下面的代码中是什么,$ arr2正在复制$ arr并将其第一个值增加一个,因此$ arr2 [0]“ 2”的结果很明显,但是$ arr发生了什么,当我像这样将引用$ arr [0]传递给$ a时,这样$ a =&$ arr [0]的结果是$ arr [0]为2,当我将其传递给值$ a = $ arr [0 [$ arr [0]的结果应设为1,应该有人启发我吗?
<?php
$a = 1;
$arr = array(1);
$a = &$arr[0];
$arr2 = $arr;
$arr2[0]++;
echo $arr[0]. "<br>";//2
echo $arr2[0]. "<br>";//2
?>
答案 0 :(得分:2)
不确定这是否是错误,但是var_dump()
可以帮助解释。
<?php
$a = 1;
$arr = array(1);
var_dump( $arr );
$a = &$arr[0];
var_dump( $arr );
$arr2 = $arr;
$arr2[0]++;
输出:
array(1) {
[0]=>
int(1)
}
array(1) {
[0]=>
&int(1)
}
在第二个&int(1)
中记下var_dump()
。这告诉我们$arr
的位置#0已变成指向PHP内存中某个位置的引用指针,而不是保留专用值。
因此,当您执行$arr2 = $arr;
时,$arr2
也会收到该引用指针。
答案 1 :(得分:2)
PHP中的引用不像指针。当您通过引用分配或传递某些内容时,您会创建我们可以称为“引用集”的内容,其中两个 变量都是对相同“ zval”的引用(内存中保存了类型和值的结构)变量)。
一个重要的后果是引用是对称的。我倾向于将引用分配写为$foo =& $bar
而不是$foo = &$bar
来强调这一点:运算符不仅会引用$bar
并将其放入$foo
,会同时影响两个操作符。
考虑到这一点,让我们看一下您的示例:
$arr = array(1);
这将创建两个zval:一个用于数组$arr
本身,另一个用于该数组(0
)位置$arr[0]
中的值。
$a =& $arr[0];
这会将$a
和$arr[0]
绑定到参考集中。无论使用哪种名称,我们都将使用以前创建的相同zval,当前使用1
。
$arr2 = $arr;
这会将$arr
的内容复制到新数组zval $arr2
中。但是它不会将数组中的引用解析为值,它只是复制它们是引用的事实。
所以$arr2[0]
现在也是包含$arr[0]
和$a
的参考集的一部分。
$arr2[0]++;
这会将参考集所指向的zval从1
增大到2
。
echo $arr[0]. "<br>";//2
echo $arr2[0]. "<br>";//2
由于它们都是同一参考集的一部分,因此它们都指向相同的zval(整数2)。
不可避免的问题是“错误还是功能?”一个更有用的示例是将包含引用的数组传递给函数:
function foo($array) {
$array[0] = 42;
$array[1] = 69;
}
$a = 1;
$b = 1;
$foo = [ &$a, &$b ];
foo($foo);
echo $a; // 42
echo $b; // 69
像赋值一样,传入函数不会破坏引用,因此操纵它们的代码可以安全地重构为多个函数。