Жесткие ссылки в PHP
Жесткая ссылка представляет собой просто переменную, которая
является синонимом другой переменной. Многоуровневые ссылки (то есть,
ссылка на ссылку на переменную, как это можно делать, например, в Perl)
не поддерживаются. Так что не стоит воспринимать жесткие ссылки
серьезнее, чем синонимы.
Чтобы создать жесткую ссылку, нужно использовать оператор & (амперсанд). Например:
$a=10;
$b = &$a; // теперь $b — то же самое, что и $a
$b=0; // на самом деле $a=0
echo "b=$b, a=$a"; // Выводит: "b=0, a=0"
Ссылаться можно не только на переменные, но и на элементы массива
(этим жесткие ссылки выгодно отличаются от символических). Например:
$A=array('a' => 'aaa', 'b' => 'bbb');
$b=&$A['b']; // теперь $b — то же, что и элемент с индексом 'b' массива
$b=0; // на самом деле $A['b']=0;
echo $A['b']; // Выводит 0
Впрочем, элемент массива, для которого планируется создать
символическую ссылку, может и не существовать. Как в следующем случае:
$A=array('a' => 'aaa', 'b' => 'bbb');
$b=&$A['c']; // теперь $b — то же, что и элемент с индексом 'c' массива
echo "Элемент с индексом 'c': (".$A['c'].")";
В результате выполнения рассмотренного скрипта, хотя ссылке $b и не было ничего присвоено, в массиве $A создастся новый элемент с ключом c и значением — пустой строкой (мы можем это определить по результату работы echo).
То есть, жесткая ссылка на самом деле не может ссылаться на
несуществующий объект, а если делается такая попытка, то объект
создается.
Примечание: Если убрать строку, в которой создается жесткая ссылка, то будет выведено сообщение о том, что элемент с ключом c не определен в массиве $A.
Жесткие ссылки удобно применять при передаче параметров пользовательской функции и возврате значения из нее.
Символические ссылки (переменные переменные)
Символическая ссылка — это всего лишь строковая
переменная, хранящая имя другой переменной. Чтобы добраться до значения
переменной, на которую ссылается символическая ссылка, необходимо
применить дополнительный знак $ перед именем ссылки. Рассмотрим пример:
$a=10;
$b=20;
$c=30;
$p="a"; // или $p="b" или $p="c" (присваиваем $p имя другой переменной)
echo $$p; // выводит переменную, на которую ссылается $p, т. е. $a
$$p=100; // присваивает $a значение 100
Мы видим, что для того, чтобы использовать обычную строковую переменную как ссылку, нужно перед ней поставить еще один символ $.Это говорит интерпретатору, что надо взять не значение самой $p, а значение переменной, имя которой хранится в переменной $p.
Символические ссылки (переменные переменные) используюся достаточно редко.
Жесткие ссылки и пользовательские функции
Передача значений по ссылке
Вы можете передавать переменные в пользовательскую функцию
по ссылке, если вы хотите разрешить функции модифицировать свои
аргументы. В таком случае, пользовательския функция сможет изменять
аргументы. Синтаксис таков:
<?php
function foo(&$var)
{
$var++;
}
$a=5;
foo($a);
// $a здесь равно 6
?>
Заметьте, что в вызове функции отсутствует знак ссылки - он есть
только в определении функции. Этого достаточно для корректной передачи
аргументов по ссылке.
Еще один интересный пример:
<?php
function funct(&$string)
{
$string .= 'а эта внутри.';
}
$str = 'Эта строка за пределами функции, ';
funct($str);
echo $str; // Выведет 'Эта строка за пределами функции, а эта внутри.'
?>
По ссылке можно передавать:
-
Переменные, например foo($a)
-
Оператор new, например foo(new foobar())
-
Ссылки, возвращаемые функцией, например:
<?php
function &bar()
{
$a = 5;
return $a;
}
foo(bar());
?>
Любое другое выражение не должно передаваться по ссылке, так как
результат не определён. Например, следующая передача по ссылке является
неправильной:
<?php
function bar() // Операция & отсутствует
{
$a = 5;
return $a;
}
foo(bar());
foo($a = 5); // Выражение, а не переменная
foo(5); // Константа, а не переменная
?>
Возврат значений по ссылке
Рассмотрим еще одну возможность пользовательских функций PHP - возврат ссылок.
Возвращение по ссылке используется в тех случаях, когда вы хотите
использовать функцию для выбора переменной, с которой должна быть
связана данная ссылка. При возвращении по ссылке используйте такой
синтаксис:
<?php
function &find_var($param)
{
/* ... код ... */
return $found_var;
}
$foo =& find_var($bar);
$foo->x = 2;
?>
В этом примере устанавливается свойство объекта, возвращённого функцией find_var, а не его копии, как было бы без использования ссылок.
Еще один пример возврата значений пользовательской функции по ссылке:
<?php
$a = 100;
/* Далее идет функция, которая возвращает ссылку */
function &s () {
global $a;
// Возвращаем ссылку на переменную $a
return $a;
}
// Присваиваем ссылку переменной $b
$b = &s();
$b = 0;
echo $a; // Выводит 0
?>
Удаление ссылок (сброс ссылок)
При удалении ссылки, просто разрывается связь имени и содержимого
переменной. Это не означает, что содержимое переменной будет разрушено.
Например:
<?php
$a = 1;
$b =& $a;
unset($a);
?>
Этот код не сбросит $b, а только $a.
И все же, жесткая ссылка — не абсолютно точный синоним объекта, на который она ссылается. Дело в том, что оператор Unset(),
выполненный для жесткой ссылки, не удаляет объект, на который она
ссылается, а всего лишь разрывает связь между ссылкой и объектом.
Итак, жесткая ссылка и переменная (объект), на которую она
ссылается, совершенно равноправны, но изменение одной влечет изменение
другой. Оператор Unset() разрывает связь между объектом и ссылкой, но объект удаляется только тогда, когда на него никто уже не ссылается.
Опять же, можно провести аналогию с вызовом unlink (в Unix).
|