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);
?>

Третє, що можуть робити посилання - це повертатися за посиланням.