PHP:通过引用分配数组元素变量的副作用

时间:2015-02-02 17:11:51

标签: php reference variable-assignment internal assign

我想知道通过引用分配PHP变量的副作用是如何工作的(请注意,我询问变量赋值,不通过引用函数传递参数;就像在C ++中,两者可以不同的是,PHP已经将这两个操作分别编程了。)

基本上,我正在寻求以下解释:

$a = array(111, 222, 333);
$dummyReferenceVariable = &$a[0];
$b = $a;
$b[0] = "change everything: both a[0] and b[0]";

创建虚拟变量后,即使$b[0]从未使用过,分配给$a[0]也会改变$dummyReferenceVariable。为什么呢?

1 个答案:

答案 0 :(得分:2)

要了解这些副作用的效果,请考虑以下代码段:

$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 ):

enter image description here

enter image description here

enter image description here

为了表明我的观点,这是程序的输出:

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)
}


请注意。这种特性仅在分配对数组元素的引用时发生,如下面简单的片段所示:

// 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)

以下是上述标量案例中发生的事情:

enter image description here