Ссылки в PHP — это средство доступа к одному и тому же содержимому переменных под разными именами. Они не похожи на указатели C; например, с их помощью нельзя выполнять арифметические операции с указателями, они не являются фактическими адресами памяти и т. д. 

Вместо этого они являются псевдонимами таблицы символов. Обратите внимание, что в PHP имя переменной и содержимое переменной различаются, поэтому одно и то же содержимое может иметь разные имена. Ближайшая аналогия с именами файлов и файлами Unix: имена переменных — это записи каталога, а содержимое переменных — это сам файл. Ссылки можно сравнить с жесткими ссылками в файловой системе Unix.

Что делают ссылки

С использованием ссылок выполняются три основные операции: присваивание по ссылке , передача по ссылке и возврат по ссылке . В этом разделе представлено введение в эти операции со ссылками для дальнейшего чтения.

Назначение по ссылке

В первом из них ссылки PHP позволяют вам сделать так, чтобы две переменные ссылались на один и тот же контент. Значение, когда вы делаете:

<?php
$a =& $b;
?>

это означает, что $a и $b указывают на одно и то же содержимое.

Примечание :

Здесь $a и $b полностью равны. $a не указывает на $b или наоборот. $a и $b указывают на одно и то же место.

Примечание :

Если вы присваиваете, передаете или возвращаете неопределенную переменную по ссылке, она будет создана.

Пример #1 Использование ссылок с неопределенными переменными

<?php
function foo(&$var) { }

foo($a); // $a is "created" and assigned to 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)
?>

Тот же синтаксис можно использовать с функциями, возвращающими ссылки:

<?php
$foo =& find_var($bar);
?>

Использование того же синтаксиса с функцией, которая не возвращает значение по ссылке, даст ошибку, как и его использование с результатом оператора new . Хотя объекты передаются как указатели, это не то же самое, что ссылки.

Предупреждение

Если вы назначаете ссылку на переменную, объявленную global внутри функции, ссылка будет видна только внутри функции. Этого можно избежать, используя массив $GLOBALS .

Пример #2 Обращение к глобальным переменным внутри функций

<?php
$var1 = "Example variable";
$var2 = "";

function global_references($use_globals)
{
    global $var1, $var2;
    if (!$use_globals) {
        $var2 =& $var1; // visible only inside the function
    } else {
        $GLOBALS["var2"] =& $var1; // visible also in global context
    }
}

global_references(false);
echo "var2 is set to '$var2'\n"; // var2 is set to ''
global_references(true);
echo "var2 is set to '$var2'\n"; // var2 is set to '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 - last element of the iterated array
?>

Хотя выражения, созданные с помощью языковой конструкции, не являются строго присваиванием по ссылке, array()они также могут вести себя как таковые, добавляя префикс &к элементу массива для добавления. Пример:

<?php
$a = 1;
$b = array(2, 3);
$arr = array(&$a, &$b[0], &$b[1]);
$arr[0]++; $arr[1]++; $arr[2]++;
/* $a == 2, $b == array(3, 4); */
?>

Обратите внимание, однако, что ссылки внутри массивов потенциально опасны. Выполнение обычного (не по ссылке) присваивания со ссылкой в ​​правой части не превращает левую часть в ссылку, но в этих обычных присваиваниях сохраняются ссылки внутри массивов. Это также относится к вызовам функций, где массив передается по значению. Пример:

<?php
/* Assignment of scalar variables */
$a = 1;
$b =& $a;
$c = $b;
$c = 7; //$c is not a reference; no change to $a or $b

/* Assignment of array variables */
$arr = array(1);
$a =& $arr[0]; //$a and $arr[0] are in the same reference set
$arr2 = $arr; //not an assignment-by-reference!
$arr2[0]++;
/* $a == 2, $arr == array(2) */
/* The contents of $arr are changed even though it's not a reference! */
?>

Другими словами, эталонное поведение массивов определяется поэлементно; ссылочное поведение отдельных элементов отделено от ссылочного состояния контейнера массива.

Передача по ссылке

Второе, что делают ссылки, — это передача переменных по ссылке. Это делается путем создания локальной переменной в функции и переменной в вызывающей области, ссылающейся на одно и то же содержимое. Пример:

<?php
function foo(&$var)
{
    $var++;
}

$a=5;
foo($a);
?>

сделает $a равным 6. Это происходит потому, что в функции foo переменная $var ссылается на то же содержимое, что и $a . Для получения дополнительной информации об этом прочитайте раздел передачи по ссылке .

Возврат по ссылке

Третье, что могут сделать ссылки, это возврат по ссылке .

Чем не являются ссылки

Как было сказано ранее, ссылки не являются указателями. Это означает, что следующая конструкция не будет делать то, что вы ожидаете:

<?php
function foo(&$var)
{
    $var =& $GLOBALS["baz"];
}
foo($bar); 
?>

Что происходит, так это то, что $var в foo будет связан с $bar в вызывающем объекте, но затем повторно связан с $GLOBALS["baz"] . Невозможно связать $bar в области вызова с чем-то еще, используя механизм ссылок, поскольку $bar недоступен в функции foo (он представлен как $var , но $var имеет только переменное содержимое, а не имя-к-адресу). привязка значения в вызывающей таблице символов). Вы можете использовать возвращаемые ссылки на ссылочные переменные, выбранные функцией.