What References Do
Оновлено: 11.05.2023
Існує три основні операції, що виконуються з посиланнями: присвоювання за посиланням, передача за посиланням та повернення за посиланням. У цьому розділі наведено вступ до цих операцій, а також посилання на додаткову літературу.
У першому випадку PHP-посилання дозволяють зробити так, щоб дві змінні посилалися на один і той самий вміст. Це означає, що коли ви робите
<?php
$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. Хоча об'єкти передаються як вказівники, це не те саме, що посилання, як пояснюється у розділі Об'єкти та посилання.
Якщо всередині функції присвоїти посилання на змінну, оголошену глобальною, то це посилання буде видимим лише всередині функції. Цього можна уникнути, використовуючи масив $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'
?>
Зауважте:
Якщо ви присвоюєте значення змінній з посиланнями в операторі 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);
?>
Третє, що можуть робити посилання - це повертатися за посиланням.