Референциите в PHP позволяват две променливи да сочат към едно и също съдържание. Така че когато правите:
<?php
$a =& $b
?>
това означава, че $a и $b сочат към едно и също съдържание.
Забележка: В случая $a и $b са напълно еднакви - нито $a сочи към $b, нито обратното - просто $a и $b сочат към едно и също място.
Забележка: Ако бъдат копирани масиви с референции, техните стойности не се дереференсират (не им се премахва референцията). Това се отнася също и за масиви, предадени по стойност във функции.
Забележка: Ако присвоите, предадете или върнете недефинирана променлива по референция, тя ще бъде създадена.
Example #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
$bar =& new fooclass();
$foo =& find_var ($bar);
?>
След PHP 5 new автоматично връща референция, така че използването на =& в този контекст е непрепоръчително и предизвиква съобщение за грешка от ниво E_STRICT.
Забележка: Неизползването на оператора & създава копие на обекта. Ако използвате $this в клас, той ще оперира върху текущата инстанция на класа. Присвояването без & ще копира инстанцията (т.е. класа) и $this ще оперира върху копието, което не винаги е желано. Обикновено ще искате да работите с една единствена инстанция с цел бързина и пестене на памет.
Въпреки че можете да използвате оператора @, за да подтиснете каквито и да е грешки в конструктора с @new, това няма да работи, в случай, че се използва израза &new. Това е ограничение в Zend Engine и поради това ще доведе до грешка на синтактичния анализатор (parser error).
Ако присвоите референция на променлива, декларирана като global (глобална) в тялото на функцията, референцията ще бъде видима единствено вътре във функцията. Можете да избегнете това като използвате масива $GLOBALS.
Example #2 Рефериране на глобални променливи в тялото на функции
<?php
$var1 = "Примерна променлива";
$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 е установена в 'Примерна променлива'
?>
Мислете за global $var; като съкращение на $var =& $GLOBALS['var'];. Така присвояването на друга референция във $var променя единствено референцията на локалната променлива.
Забележка: Ако присвоявате стойност на променлива чрез референции в конструкцията foreach, референциите се променят също.
Example #3 Референции и конструкцията foreach
<?php
$ref = 0;
$row =& $ref;
foreach (array(1, 2, 3) as $row) {
// прави нещо
}
echo $ref; // 3 - последния елемент от итерирания масив
?>
Второто нещо, което правят референциите, е да предават променливи по референция. Това става чрез насочването на локалната променлива във функцията и променливата в извикващия обхват към едно и също съдържание. Пример:
<?php
function foo (&$var)
{
$var++;
}
$a=5;
foo ($a);
?>
ще увеличи $a на 6. Това се случва, защото във функцията foo променливата $var сочи към същото съдържание като $a. За повече информация вижте раздел предаване по референция.
Третото нещо, което референцията прави е връщане по референция.