提问人:Pacerier 提问时间:7/8/2013 最后编辑:Pacerier 更新时间:3/30/2015 访问量:246
为什么当 PHP 数组的元素被引用分配时会被修改?
Why does a PHP array get modified when it's element is reference-assigned?
问:
当 ref 分配数组的元素时,数组的内容将被修改:
$arr = array(100, 200);
var_dump($arr);
/* shows:
array(2) {
[0]=>
int(100) // ← ← ← int(100)
[1]=>
int(200)
}
*/
$r = &$arr[0];
var_dump($arr);
/* shows:
array(2) {
[0]=>
&int(100) // ← ← ← &int(100)
[1]=>
int(200)
}
*/
Live run.(Zend Engine 可以正常工作,而 HHVM 显示“进程退出,代码为 153”。
为什么要修改元素?
为什么我们看到而不是?&int(100)
int(100)
这似乎很奇怪。这种奇怪的解释是什么?
答:
7赞
deceze
7/8/2013
#1
我不久前已经回答了这个问题,但现在找不到答案。我相信它是这样的:
引用只是符号表中相同值的“附加”条目。符号表只能包含它指向的值,而不能包含值中的值。符号表不能指向数组中的索引,它只能指向一个值。因此,当您要引用数组索引时,将从数组中取出该索引处的值,为其创建一个符号,并且数组中的插槽获取对该值的引用:
$foo = array('bar');
symbol | value
-------+----------------
foo | array(0 => bar)
$baz =& $foo[0];
symbol | value
-------+----------------
foo | array(0 => $1)
baz | $1
$1 | bar <-- pseudo entry for value that can be referenced
因为这是不可能的:
symbol | value
-------+----------------
foo | array(0 => bar)
baz | &foo[0] <-- not supported by symbol table
以上只是一个任意选择的“伪”名称,它与实际的PHP语法或内部实际引用值的方式无关。$1
根据注释中的要求,以下是符号表通常与引用的行为方式:
$a = 1;
symbol | value
-------+----------------
a | 1
$b = 1;
symbol | value
-------+----------------
a | 1
b | 1
$c =& a;
symbol | value
-------+----------------
a, c | 1
b | 1
评论
0赞
Pacerier
8/8/2013
@deceze,您在符号值表中使用的字符令人困惑......您将如何在这条线之后绘制符号值表?(只需要它作为参考,以正确理解您在这里的意思)$a = 1; $b = 1; $c =& $a;
0赞
Pacerier
8/8/2013
@deceze。Ic,所以在行之后,而不是,你实际上意味着我们做对了?$baz =& $foo[0];
baz | $1
$1 | 'bar'
baz, $1 | 'bar'
0赞
deceze
8/8/2013
@Pacerier 这是另一种看待它的方式。我不知道说它指的是值,是一个伪链接,也指同一个值,这是否更正确;或者是否两者都引用引用值的伪链接。但是,是的,你明白了。$baz
$foo[0]
$baz
$foo[0]
0赞
Pacerier
8/8/2013
@deceze,嗯,我不太明白你所说的“伪链接”是什么意思。难道不是两个不同的符号指向同一个 zval 容器 [type='string', value='baz', refcount=2, is_ref=true]吗?$baz
$foo[0]
0赞
deceze
8/8/2013
@Pacerier 差不多。 不能是符号。 是保存数组的符号。该数组的索引是对符号表中包含您提到的 zval 的条目的引用,也引用了该 zval(无论是直接还是间接)。$foo[0]
foo
[0]
bar
评论