Как работают ссылки в PHP - Форум электронных новостей
Вход


Мини-чат
200


Нажимай , если не слабо !


РЕКЛАМА


Приветствую Вас, Гость · RSS 21.06.2025, 05:35
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Как работают ссылки в PHP
ChevyДата: Среда, 24.08.2011, 15:30 | Сообщение # 1
Chevy
Администраторы
Генералиссимус
"Нет титула"
Сообщений: 85
Offline
Данная статья предназначена для тех программистов, кто имеет опыт программирования в других языках и только начал изучать PHP, и для тех из начинающих, кто уже уверенно понимает суть языка и его основные примитивы (синтаксис, переменные, функции, типы данных).

Многие программисты, которые пришли в PHP из компилируемых языков (таких, как C и Pascal), невольно путают ссылки в PHP с указателями. В то же время, начинающие программисты без опыта вообще не понимают, что такое ссылки и как их использовать.

Терминология в статье

В данной статье используются следующие термины:
Переменная - Переменная PHP ($foo) или обращение к элементу массива ($foo['bar'][3]). Другими словами - это то, что можно передать в синтаксические конструкии isset(), unset(), empty() и т.п.
Значение - значение, которое хранится в Переменной.
Таблица переменных, Таблица - некий логический объект для визуального представления происходящего.

Таблица переменных

Где-то в недрах ядра PHP существует Таблица переменных. В этой Таблице в том или ином виде хранятся Переменные, Значения, и связь между ними. Для наглядности Таблицу переменных можно представить следующим образом:

Рис.1

В левой половине - Переменные, в правой - Значения. Стрелки показывают связь Переменной со Значением. В данной примере изображены две переменные:
Код PHP

$foo = 2;
$bar = 'lol';
Важно
Стрелки символизируют одностороннюю связь: Переменной важно знать свое Значение, но Значению совершенно все равно, к какой(-им) Переменной оно принадлежит.
Связь (стрелка на изображении) может идти только от Переменной только к Значению.
Каждая Переменная всегда имет ровно одну связь (ссылается на одно Значение).
Итак, давайте разбираться.

Простейшая ситуация

Самая простая ситуация со ссылками записывается кодом так:
Код PHP

$foo = 5;
$bar = &$foo;
После выполнения 1-й строки в Таблицу переменных заносится Переменная $foo и ее Значение 5. Выполнение 2-й строки создает Переменную $bar и устанавливает связь со Значением Переменной $foo, как показано на Рис.2 красной стрелкой.

Рис.2

Что это значит? Операция присваивания по ссылке заставляет Переменную ссылаться на уже существующее Значение другой Переменной.
Обычное присваивание в существующую Переменную изменяет ее существующее Значение.
Обычное присваивание в несуществующую Переменную создает новое Значение в Таблице.

А теперь вполне логичный вопрос: Чем отличаются между собой связи, изображенные на Рис.2? Ответ: ничем, они абсолютно одинаковы. Если в коде выше поменять переменные местами:
Код PHP

$bar = 5;
$foo = &$bar;
то Таблица переменных будет выглядеть абсолютно так же (если не брать в расчет порядок создания Переменных).

Более того, каждое Значение знает, сколько Переменных на него ссылаются (количество стрелок на рисунке). В литературе это число называется счетчик ссылок (references counter).

Удаление Переменных

Продолжаем манипуляции над Таблица переменных, изображенной на Рис.2. Удаляем первую переменную после создания ссылки:
Код PHP

$foo = 5;
$bar = &$foo;
unset($foo);
Это изменение отобразится в Таблице следующим образом:

Рис.3

Оператор unset() удаляет Переменную и исходящую от нее связь. Почему же при этом не удаляется Значение 5? Потому что еще остались другие Переменные, которые на него ссылаются.

Далее удаляем вторую переменную:
Код PHP
1
unset($bar);
Аналогично, из Таблицы удаляется Переменная $bar и ее связь со значением. После этого оказывается, что у Значения количество ссылок стало равным нулю, а это значит, что данное Значение тоже удаляется (Рис.4).

Рис.4

Массивы

Более сложные для понимания вещи поджидают нас при махинациях с массивами. Итак, создаем простой массив с тремя элементами:
Код PHP
1
$arr = array(1 => 10, 2 => 20, 3 => 30);
Как его отобразить в Таблице переменных? Весь массив целиком - это Значение, ибо на него ссылается Переменная $arr. Также, можно заставить другую Переменную ссылаться на Значение любого элемента массива, поэтому 10, 20 и 30 - также должны быть отдельными Значениями.

Рис.5

Здесь #1 - это некий идентификатор массива для внутреннего представления.

Чтобы прочитать значение элемента массива
Код PHP
1
echo $arr[2];
необходимо пройти через две связи в Таблице.

Ссылки и Массивы

Итак, к только что созданному массиву начинаем применять ссылки:
Код PHP

$arr = array(1 => 10, 2 => 20, 3 => 30);
$foo = &$arr;
$bar = &$arr[2];
Поскольку мы уже знаем, как расположить массив в Таблице переменных, добавить две Переменные со ссылками на существующие Значения не составит труда.

Рис.6

Затем выполняем обычное присваивание:
Код PHP
1
$arr[1] = $arr[2];
Порядок действий таков:
Для правой части присваивания в Таблице ищем Переменную $arr - находим массив #1.
В массиве #1 ищем элемент с ключем 2 - находим Значение 20.
Для левой части аналогично ищем Переменную $arr - находим массив #1.
Аналогично в массиве #1 ищем элемент с ключем 1 - находим Значение 10.
В найденное в п.4 Значение 10 копируем найденное в п.2 Значение 20.

Перечисленным действиям соответствуют оранжевые цифры на Рисунке 7.

Рис.7

Далее делаем присваивание по ссылке:
Код PHP
1
$arr[2] = &$arr[3];
Существующая связь от Переменной #1[2] разрывается и создается новая связь до Значения 30.

Рис.8

Если теперь уничтожить переменную $arr
Код PHP
1
unset($arr);
то из Таблицы будет удалена соответвтсующая Переменная и ее связь. Поскольку на Значение #1 все еще ссылается другая Переменная, то оно не будет уничтожено.

Рис.9

Последний шаг порождает более интересные вещи:
Код PHP
1
$foo = 42;
Значение #1, на которое ссылается Переменная $foo, заменяется новым Значением 42. Что значит "заменяется"? Это значит, что старое #1 удаляется. Это приводит к удалению Переменных #1[1], #1[2] и #1[3] вместе с их связями. Тут же оказываются бесхозными два Значения, поэтому они тоже удаляются.

Рис.10

В результате остается две простых пары Переменная - Значение.
  • Страница 1 из 1
  • 1
Поиск:

Хостинг от uCoz