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

时间:2012-02-24 02:43:13

标签: php arrays reference

当我运行代码时:

$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" }

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

2 个答案:

答案 0 :(得分:3)

免责声明:我未能找到明确的参考资料,因此我主要在此推断。

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

$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和{{1}分开}}本身成为对存储$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的值。

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

答案 1 :(得分:2)

这是brought up in the docs,页面上comments之一实际上提到了这种特定行为。