免责声明:我未能找到明确的参考资料,所以我在这里主要推断.
常规引用通过符号表工作.创建变量和值时,两者都存储在本地符号表中,如下所示:
$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都会引用它.
正如我所说,这可能是也可能不是对内部发生的事情的准确解释,但它说明了原则.