为什么当数组元素更改时,按值分配给数组元素的变量(在早期的按引用分配之后)会发生变化


Why does a variable assigned by value to an array element (after an earlier assign-by-reference) change when the array element is changed?

当我运行代码打击时:

$var[0] = 'a';
$tmp = $var;
$var[0] = 'b';
var_dump($tmp); 

输出为:

array(1) { [0]=> string(1) "a" }

当我添加一行时,如下所示:

$var[0] = 'a';
$foo = & $var[0]; # added line
$tmp = $var;
$var[0] = 'b';
var_dump($tmp); 

输出变为:

array(1) { [0]=> &string(1) "b" }

如果我通过引用数组的元素$var[0] $foo赋值来分配变量,变量$tmp值分配给数组$var应该这样改变吗?为什么会这样?

免责声明:我无法找到明确的参考,所以我在这里主要是推断。

常规引用通过符号表工作。创建变量和值时,两者都存储在本地符号表中,如下所示:

$foo = "bar";
+--------+-------+
| symbol | value |
+--------+-------+
| $foo   | "bar" |
+--------+-------+

创建引用时,这只是将相同值的另一个符号添加到表中:

$bar =& $foo;
+------------+-------+
| symbol     | value |
+------------+-------+
| $foo, $bar | "bar" |
+------------+-------+

但是,数组键的存储方式不同:

$var[0] = 'a';
+--------+-----------------+
| symbol | value           |
+--------+-----------------+
| $var   | array(0 => 'a') |
+--------+-----------------+

符号表中有一个用于$var的条目,但数组中的值不会在符号表中单独引用。在创建对值'a'(存储在 $var[0] 中(的引用时,我推断必须发生的是,值'a'与数组$var分离,并且$var[0]本身成为对存储'a'的新位置的引用:

$foo =& $var[0];
+--------+------------------+
| symbol | value            |
+--------+------------------+
| $var   | array(0 => %REF) |
| $foo   | %REF             |
| %REF   | 'a'              |
+--------+------------------+

我猜符号表的内部实现不允许创建对数组键的直接引用,因此这是创建对数组元素的引用的唯一方法。

因此,当将$var复制到$tmp时,引用将随之复制:

$tmp = $var;
+--------+------------------+
| symbol | value            |
+--------+------------------+
| $var   | array(0 => %REF) |
| $foo   | %REF             |
| %REF   | 'a'              |
| $tmp   | array(0 => %REF) |
+--------+------------------+

然后,当更改$var[0]引用的值时,它会更改 %REF 的值,$tmp$var 都引用该值。

正如我所说,这可能是也可能不是对内部发生的事情的准确解释,但它说明了原则。

这是在文档中提出的,页面上的评论之一实际上提到了这种特定行为。