【问题标题】:Why does a PHP array get modified when it's element is reference-assigned?为什么 PHP 数组在其元素被引用分配时会被修改?
【发布时间】:2015-03-30 21:23:53
【问题描述】:

当引用分配数组的元素时,数组的内容会被修改:

$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)

这看起来很奇怪。这种奇怪的解释是什么?

  • 我无法使用提供的代码重现这一点。使用 PHP 5.4.6
  • 我已经检查过了,真的很奇怪。因为没有任务。我检查了writecodeonline.com/php
  • @Robert 可以在这里重现,PHP_VERSION 在这里是 5.4.15
  • 即使在 php 4 中也有相同的行为

标签: php arrays reference php-internals


【解决方案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

上面的$1 只是一个任意选择的“伪”名称,它与实际的 PHP 语法或内部实际引用该值的方式无关。

根据 cmets 的要求,这里的符号表如何通常与引用一起表现:

$a = 1;

symbol | value
-------+----------------
a      | 1


$b = 1;

symbol | value
-------+----------------
a      | 1
b      | 1


$c =& a;

symbol | value
-------+----------------
a, c   | 1
b      | 1

【讨论】:

  • @deceze,人物您在符号值表中使用的内容令人困惑...您将如何在$a = 1; $b = 1; $c =&amp; $a; 这一行之后绘制符号值表? (只需将其作为参考以正确理解您的意思)
  • @deceze。 Ic,所以在$baz =&amp; $foo[0]; 之后,而不是baz | $1 $1 | 'bar',你实际上的意思是我们得到baz, $1 | 'bar' 对吗?
  • @Pacerier 这是另一种看待它的方式。我不知道说$baz 指的是值,$foo[0] 是伪链接,它也指的是相同的值是否更正确;或者$baz$foo[0] 是否都引用了引用该值的伪链接。但是,是的,你明白了。
  • @deceze,嗯,我不太明白你的意思“伪链接”.. 不只是$baz$foo[0] 是指向同一个zval 容器[type='string', value='baz', refcount=2, is_ref=true] 的两个不同符号吗?
  • @Pacerier 几乎。 $foo[0] 不能是象征. foo 是一个包含数组的符号。该数组的索引[0] 是对符号表中包含您提到的zval 的条目的引用,bar 也指的是该zval(无论是直接还是间接)。
猜你喜欢
  • 2013-07-05
  • 1970-01-01
  • 2016-04-19
  • 1970-01-01
  • 1970-01-01
  • 2019-08-11
  • 2012-06-15
  • 2017-09-12
相关资源
最近更新 更多