Когда ref-assigning элемент массива, содержимое массива изменяется:
$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) } */
Прямой эфир. (Zend Engine отлично справится, в то время как HHVM показывает «Процесс завершен с кодом 153».)
Почему элемент изменен?
Почему мы видим &int(100)
вместо int(100)
?
Это кажется совершенно странным. Какое объяснение этой странности?
Я ответил на это некоторое время назад, но не могу найти ответ прямо сейчас. Я считаю, что это было так:
Ссылки – это просто «дополнительные» записи в таблице символов для того же значения. Таблица символов может иметь только значения, на которые указывает, а не значения в значениях. Таблица символов не может указывать на индекс в массиве, он может указывать только на значение. Поэтому, когда вы хотите сделать ссылку на индекс массива, значение в этом индексе выводится из массива, для него создается символ, а в слоте в массиве появляется ссылка на значение:
$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 или с тем, как на самом деле ссылается на внутреннее значение.
Как указано в комментариях, здесь, как обычно используется таблица символов со ссылками:
$a = 1; symbol | value -------+---------------- a | 1 $b = 1; symbol | value -------+---------------- a | 1 b | 1 $c =& a; symbol | value -------+---------------- a, c | 1 b | 1