【问题标题】:PHP: Side-effects of assigning an array element variable by referencePHP:通过引用分配数组元素变量的副作用
【发布时间】:2015-04-01 17:03:35
【问题描述】:

我想知道通过引用分配 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。为什么?

【问题讨论】:

  • 请不要发布不完整的问题。
  • nikic.github.io/2012/03/28/… 是一个好的开始
  • 所以看起来您正在尝试制定规范的问题/答案对。要使用它,question 必须和答案一样好。您提出的问题过于宽泛,有立即被关闭的危险。
  • 我觉得我的回答比较完整。如果我遗漏了任何重要细节,或者是否可以改进,请告诉我。谢谢。
  • 如果您可以编辑问题以使其具体化,它可能会在关闭后继续存在,或者如果它确实关闭,则可以重新打开。

标签: php reference variable-assignment internal assign


【解决方案1】:

要了解这些副作用是如何起作用的,请考虑以下 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)

这是在上述标量情况下发生的幕后情况:

【讨论】:

    猜你喜欢
    • 2017-04-15
    • 1970-01-01
    • 1970-01-01
    • 2013-05-28
    • 2020-10-21
    • 2017-10-24
    • 1970-01-01
    • 1970-01-01
    • 2022-11-27
    相关资源
    最近更新 更多