Присваивание по ссылке
Первое, что делают ссылки в PHP, — разрешают создавать две переменные,
которые ссылаются на одно и то же значение. Когда выражение записывают вот так:
переменные
$a и
$b указывают
на одно и то же значение.
Замечание:
Переменные $a и $b, которые приводит пример, — эквивалентны.
Переменная $a не указывает на переменную $b
или наоборот. Переменные $a
и $b указывают на одно и то же значение.
Замечание:
PHP создаст переменную, если неинициализированную переменную
присвоили, передали или вернули по ссылке.
Пример #1 Пример присваивания ссылок с неопределёнными переменными
<?php
function foo(&$var) {}
foo($a); // PHP создал переменную $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.
Объекты хотя и передаются как указатели, это не то же, что ссылки, как объясняет
раздел «Объекты и ссылки».
Внимание
Ссылка будет видна только внутри функции, если присвоить ссылку переменной,
которую объявили внутри функции через ключевое слово global
.
Чтобы избежать этого и сделать ссылку видимой в глобальном контексте,
ссылку присваивают переменной суперглобального массива $GLOBALS.
Пример #2
Пример присваивания ссылок переменным, которые объявили внутри функции через ключевое слово global
<?php
$var1 = "Пример переменной";
$var2 = "";
function global_references($use_globals)
{
global $var1, $var2;
if (!$use_globals) {
$var2 =& $var1; // Ссылка $var1 видна только внутри функции
} else {
$GLOBALS["var2"] =& $var1; // Ссылка $var1 видна также в глобальном контексте
}
}
global_references(false);
echo "Переменной \$var2 установили значение '$var2'\n"; // Переменной $var установили значение ''
global_references(true);
echo "Переменной \$var2 установили значение '$var2'\n"; // Переменной $var установили значение 'Пример переменной'
?>
Об инструкции
global $var;
думают как о сокращённой записи
выражения
$var =& $GLOBALS['var'];
, в котором переменной
присваивается ссылка. Поэтому присваивание переменной
$var
другой ссылки
изменяет ссылку только локальной переменной.
Замечание:
Когда в инструкции foreach
значение присваивается переменной, которая хранит ссылку,
значение ссылки тоже изменяется.
Пример #3 Пример ссылок в конструкции foreach
<?php
$ref = 0;
$row =& $ref;
foreach (array(1, 2, 3) as $row) {
// Сделать что-нибудь
}
echo $ref; // 3 — значение последнего элемента массива, который перебирался в цикле
?>
Выражения с языковой конструкцией array()
умеют вести себя как присваивание по ссылке, хотя и не через строгий синтаксис присваивания по ссылке,
а путём добавления префикса &
к добавляемому элементу массива. Приведём пример:
Однако обратите внимание, что ссылки внутри массивов несут опасность.
Стандартные (не по ссылке) присваивания со ссылкой в правой части
не превращают левую часть в ссылку, но ссылки внутри массивов сохраняются
при стандартных присваиваниях.
Это также относится к вызовам функций, в которых массив передаётся по значению. Приведём пример:
Другими словами, ссылочное поведение массивов определяется поэлементно;
ссылочное поведение отдельных элементов массива не зависит от ссылочного статуса
контейнера массива.
Передача по ссылке
Второе, что умеют делать ссылки, — передавать переменные по ссылке. Для этого создают
две переменные, которые ссылаются на одно и то же содержимое: одну — в функции, а другую —
в области видимости вызова. Следующий пример:
изменит значение, на которое указывает переменная
$a, на 6. Причина состоит в том,
что в функции
foo переменная
$var
ссылается на то же содержимое, что и переменная
$a. Дополнительную
информацию об этом даёт раздел
о передаче по ссылке.