要了解这些副作用是如何起作用的,请考虑以下 sn-p:
$a = array(111, 222, 333);
$b = $a;
$b[0] = 999;
var_dump($a, $b);
$dummyReferenceVariable = &$a[0];
$dummyReferenceVariable = 444;
var_dump($a, $b);
$c = $a;
$d = $b;
var_dump($a, $b, $c, $d);
$a[0] = 555;
$b[0] = 666;
$c[0] = 777;
$d[0] = 888;
var_dump($a, $b, $c, $d);
我将用下图说明幕后发生的事情(this post 已经涵盖了数组按值分配时内部发生的事情),其答案中的示例与此示例相同,尽管问题问的是不同的:
注意:在图表中,橙色链接的行为使得当指向数组元素所属的数组被分配时,数组副本中的相应数组元素将指向与 相同的位置写时复制已禁用。另一方面,黑色链接表示当一个数组元素被赋值时,该值将被复制到一个新的内存位置(copy-on-write):
为了说明我的意思,这是程序的输出:
array(3) {
[0]=>
int(111)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
int(999)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
&int(444)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
int(999)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
&int(444)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
int(999)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
&int(444)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
int(999)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
&int(777)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
int(666)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
&int(777)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
int(888)
[1]=>
int(222)
[2]=>
int(333)
}
注意。这种特性仅在分配对数组元素的引用时才会发生,正如以下简单的 sn-p 所证实的那样:
// ASSIGNING REFERENCE VALUES TO SCALARS (INSTEAD OF ARRAY ELEMENTS) WORK AS EXPECTED:
$a = 111;
$aRef = &$a;
$a = 222;
var_dump($a, $aRef); // 222, 222
$aRef = 333;
var_dump($a, $aRef); // 333, 333
$c = $a;
$d = $aRef;
$c = 444;
$d = 555;
var_dump($a, $aRef, $c, $d); // 333, 333, 444, 555
按预期输出以下内容:
int(222)
int(222)
int(333)
int(333)
int(333)
int(333)
int(444)
int(555)
这是在上述标量情况下发生的幕后情况: