Есть три основных операции с использованием ссылок: присвоение по ссылке, передача по ссылке, и возврат по ссылке. Данный раздел познакомит вас с этими операциями и предоставит ссылки для дальнейшего изучения.
Для начала, ссылки PHP позволяют создать две переменные указывающие на одно и тоже значение. Таким образом, когда выполняется следующее:
<?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
$foo =& find_var($bar);
?>
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'
?>
Замечание:
При использовании переменной-ссылки в foreach, изменяется содержание, на которое она ссылается.
Пример #3 Ссылки и foreach
<?php
$ref = 0;
$row =& $ref;
foreach (array(1, 2, 3) as $row) {
// do something
}
echo $ref; // 3 - последнее значение, используемое в цикле
?>
Хотя, стого говоря, в выражениях, создаваемых с помощью конструкции 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
/* Присвоение скалярных переменных */
$a = 1;
$b =& $a;
$c = $b;
$c = 7; //$c не ссылка и не изменяет значений $a и $b
/* Присвоение массивов */
$arr = array(1);
$a =& $arr[0]; //$a и $arr[0] ссылаются на одно значение
$arr2 = $arr; //присвоение не по ссылке!
$arr2[0]++;
/* $a == 2, $arr == array(2) */
/* Содержимое $arr изменилось, хотя было присвоено не по ссылке! */
?>
Второе, что делают ссылки - передача параметров по ссылке. При этом локальная переменная в функции и переменная в вызывающей области видимости ссылаются на одно и то же содержимое. Пример:
<?php
function foo(&$var)
{
$var++;
}
$a=5;
foo($a);
?>
Третье, что могут делать ссылки - это возврат по ссылке.