Присвоение по ссылке
Для начала, ссылки PHP позволяют создать две переменные
указывающие на одно и тоже значение. Таким образом, когда выполняется следующее:
то
$a указывает на то же значение
что и
$b.
Замечание:
$a и $b здесь абсолютно эквивалентны,
но это не означает, что $a указывает на $b
или наоборот. Это означает, что $a
и $b указывают на одно и тоже значение.
Замечание:
При присвоении, передаче или возврате неинициализированной переменной по ссылке,
происходит ее создание.
Пример #1 Использование ссылок с неинициализированными переменными
<?php
function foo(&$var) { }
foo($a); // $a создана и равна null
$b = array();
foo($b['b']);
var_dump(array_key_exists('b', $b)); // bool(true)
$c = new StdClass;
foo($c->d);
var_dump(property_exists($c, 'd')); // bool(true)
?>
Такой же синтаксис можно использовать и в функциях, возвращая ссылки,
а так же в операторе new (начиная с PHP 4.0.4 и до PHP 5.0.0):
Начиная с PHP 5,
new
автоматически возвращает объекты по ссылке, поэтому использовать
=& в этом случае нерекомендуется и вызывает
сообщение
E_DEPRECATED в PHP 5.3 и последующих версиях,
а также сообщение
E_STRICT в более ранних версиях.
(Технически разница в том, что в PHP 5 переменные объектов, так же как и ресурсы,
являются просто указателями на реальные данные объекта, поэтому ссылки на объекты
не те же самые "ссылки", о которых говорилось ранее (псевдонимы).
Подробнее в
Объекты
и ссылки.)
Внимание
Если переменной, объявленной внутри функции как
global, будет присвоена ссылка, она будет видна только
в функции. Чтобы избежать этого, используйте массив $GLOBALS.
Пример #2 Присвоение ссылок глобальным переменным внутри функции
<?php
$var1 = "Example variable";
$var2 = "";
function global_references($use_globals)
{
global $var1, $var2;
if (!$use_globals) {
$var2 =& $var1; // только локально
} else {
$GLOBALS["var2"] =& $var1; // глобально
}
}
global_references(false);
echo "значение var2: '$var2'\n"; // значение var2: ''
global_references(true);
echo "значение var2: '$var2'\n"; // значение var2: 'Example variable'
?>
Думайте о
global $var; как о сокращении от
$var =& $GLOBALS['var'];. Таким образом,
присвоение
$var другой ссылки влияет лишь на локальную
переменную.
Замечание:
При использовании переменной-ссылки в foreach,
изменяется содержание, на которое она ссылается.
Пример #3 Ссылки и foreach
<?php
$ref = 0;
$row =& $ref;
foreach (array(1, 2, 3) as $row) {
// do something
}
echo $ref; // 3 - последнее значение, используемое в цикле
?>
Хотя, стого говоря, в выражениях, создаваемых с помощью конструкции
array(),
нет присвоения, но тем не менее можно указать префикс
& для элементов массива. Пример:
Однако следует отметить, что ссылки в массивах являются потенциально опасными.
При обычном (не по ссылке) присвоении массива, ссылки
внутри этого массива сохраняются. Это также относится
и к вызовам функций, когда массив передается по значению. Пример:
Иными словами, поведение отдельных элементов массива
не зависит от типа присвоения этого массива.
Pass By Reference
Второе, что делают ссылки - передача параметров по ссылке. При этом
локальная переменная в функции и переменная в вызывающей области видимости
ссылаются на одно и то же содержимое. Пример:
Этот код присвоит
$a значение 6. Это происходит, потому
что в функции
foo переменная
$var
ссылается на то же содержимое, что и переменная
$a. См.
также детальное объяснение
передачи по ссылке.