&
по-разному используется в PHP для обозначения ссылок ( см. Этот раздел руководства ), но вводить его в заблуждение, считая его оператором само по себе, неверно. Вот почему некоторые люди предпочитают писать $foo =& $bar
вместо $foo = &$bar
- это означает то же самое, но подчеркивает, что "reference-y-ness" является свойством присваивания, а не переменных.
В некоторых языках программирования, таких как C или C ++, вы можете «получить ссылку на» определенную переменную; результирующее значение может быть передано как отдельная сущность, а затем «разыменовано», чтобы выяснить, куда оно указывает. Это не что такое ссылки PHP.
Вместо этого все переменные PHP на самом деле являются ссылками на внутренний тип, называемый zval
. Вы не можете напрямую манипулировать zval
s в PHP, и при этом вы не можете создавать дополнительные слои косвенности - каждая переменная является ссылкой на zval
, и все. (См. Предостережение: объекты ниже.)
То, что делает назначение по ссылке ($foo =& $bar
), передача по ссылке (function foo(&$bar) { ... }
) или возврат по ссылке (return &$foo
), говорит PHP, что вы хотите, чтобы две переменные указать на то же zval
. Обратите внимание, что вы не указываете одну переменную «на» другую - они обе одинаково «реальны», и вызов unset()
для любой из них оставит другую полностью без изменений.
Предостережение: объекты
Часто вводят в заблуждение, что, поскольку объекты PHP5 "всегда передаются по ссылке". Правда в том, что у них есть дополнительный слой косвенности, где zval
сам по себе является указателем на конкретный объект. Это дает нам три разные вещи, на которые мы можем ссылаться: переменная , zval
, на которую она указывает, и объект , на который она указывает:
// Create an object, and point three variables at it in different ways:
$foo = new stdClass;
$bar_by_value = $foo;
$bar_by_ref =& $foo;
// Change the object: updates the object shared by all three variables
$foo->value = 42;
// Change the value (zval) of $foo: will update $bar_by_ref,
// but $bar_by_value still points at the original object
$foo = 42;
// Change the variable itself: will never affect $bar_by_value or $bar_by_ref
unset($foo);