13208 / 6596 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Как работают ссылки в PHP05.08.2010, 20:27. Показов 62459. Ответов 3
Обсуждение статьи
Как работают ссылки в PHP От автора Данная статья предназначена для тех программистов, кто имеет опыт программирования в других языках и только начал изучать PHP, и для тех из начинающих, кто уже уверенно понимает суть языка и его основные примитивы (синтаксис, переменные, функции, типы данных). Многие программисты, которые пришли в PHP из компилируемых языков (таких, как C и Pascal), невольно путают ссылки в PHP с указателями. В то же время, начинающие программисты без опыта вообще не понимают, что такое ссылки и как их использовать. Терминология в статье В данной статье используются следующие термины:
Таблица переменных Где-то в недрах ядра PHP существует Таблица переменных. В этой Таблице в том или ином виде хранятся Переменные, Значения, и связь между ними. Для наглядности Таблицу переменных можно представить следующим образом: Рис.1 В левой половине - Переменные, в правой - Значения. Стрелки показывают связь Переменной со Значением. В данной примере изображены две переменные:
Простейшая ситуация Самая простая ситуация со ссылками записывается кодом так:
Рис.2 Что это значит? Операция присваивания по ссылке заставляет Переменную ссылаться на уже существующее Значение другой Переменной. Обычное присваивание в существующую Переменную изменяет ее существующее Значение. Обычное присваивание в несуществующую Переменную создает новое Значение в Таблице. А теперь вполне логичный вопрос: Чем отличаются между собой связи, изображенные на Рис.2? Ответ: ничем, они абсолютно одинаковы. Если в коде выше поменять переменные местами:
Более того, каждое Значение знает, сколько Переменных на него ссылаются (количество стрелок на рисунке). В литературе это число называется счетчик ссылок (references counter). Удаление Переменных Продолжаем манипуляции над Таблица переменных, изображенной на Рис.2. Удаляем первую переменную после создания ссылки:
Рис.3 Оператор unset() удаляет Переменную и исходящую от нее связь. Почему же при этом не удаляется Значение 5? Потому что еще остались другие Переменные, которые на него ссылаются. Далее удаляем вторую переменную:
Рис.4 Массивы Более сложные для понимания вещи поджидают нас при махинациях с массивами. Итак, создаем простой массив с тремя элементами:
Рис.5 Здесь #1 - это некий идентификатор массива для внутреннего представления. Чтобы прочитать значение элемента массива
Ссылки и Массивы Итак, к только что созданному массиву начинаем применять ссылки:
Рис.6 Затем выполняем обычное присваивание:
Перечисленным действиям соответствуют оранжевые цифры на Рисунке 7. Рис.7 Далее делаем присваивание по ссылке:
Рис.8 Если теперь уничтожить переменную $arr
Рис.9 Последний шаг порождает более интересные вещи:
Рис.10 В результате остается две простых пары Переменная - Значение.
32
|
05.08.2010, 20:27 | |
Ответы с готовыми решениями:
3
Как с php отправить данные ссылки обратно PHP функции file_exists, is_file, is_readable не работают с кириллицей. Как быть? Не работают символы к php Cеансы в PHP,не работают скрипты |
13208 / 6596 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
|
||||||||||||||||||||||||||
05.08.2010, 20:32 [ТС] | 2 | |||||||||||||||||||||||||
Неявные ссылки
Помимо явного использования ссылок (присваивание по ссылке и передача аргументов по ссылке) существуют также несколько вариантов неявного использования ссылок. Доступ к глобальным переменным из функции Как Вам известно, глобальные переменные сами по себе недоступны внутри функций. Например, в приведенном коде:
Чтобы получить доступ к глобальной переменной внутри функции, необходимо использовать оператор global:
А теперь самое интересное. Задумывались ли Вы, как это работает? Что будет, если перед оператором global использовать такую же локальную переменную? Что будет, если внутри функции после оператора global удалить переменную? Ответ на первый вопрос очень прост и описан в документации PHP. Оператор global создает ссылку на значение одноименной глобальной переменной. Иными словами, это эквивалентно присваиванию по ссылке из глобальной переменной в локальную. Это значит, что если перед оператором global уже была такая же локальная переменная, то у ее значения уменьшится количество ссылок. Если после оператора global удалить эту переменную, то удалится всего лишь локальная переменная со своей ссылкой, а глобальная переменная никуда не денется. После этого с переменной можно работать, как с локальной:
Статические переменные Статические переменные видны только внутри функции, как локальные переменные, но их значение сохраняется между вызовами функции. Чтобы декларировать статическую переменную, необходимо использовать оператор static.
На самом деле оператор static при первом вызове создает Значение, которое не уничтожается, когда на него больше не ссылается ни одна Переменная. Указанная переменная $foo становится ссылкой на это Значение. Если перед оператором static уже была одноименная локальная переменная, то, аналогично оператору global, ее связь со старым значением разрывается. Если после оператора static удалить переменную, то ее статическое Значение останется в памяти на своем месте (даже если удалить все ссылающиеся на него Переменные).
22
|
13208 / 6596 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
|
||||||||||||||||
04.09.2010, 13:34 [ТС] | 3 | |||||||||||||||
Ссылки и объекты
Важно! Нижеизложенное справедливо только для PHP версии 5 и выше.При работе с ООП в PHP мы сталкиваемся со ссылками другого рода: ссылками на объект. Здесь важно не запутаться в терминологии. Для ясности небольшой пример:
Заметьте, что в данном примере идет обычное присваивание, и нет присваивания по ссылке. Дополнительная терминология Итак, появились два разных по смыслу термина "Ссылка". Чтобы избежать путаницы, будем называть "Ссылкой" именно те ссылки, о которых рассказывает вся статья. А ссылки на объекты (те самые номерки от курток) будем называть "Ссылками на объект" или "Ссылками объектов". Ссылка на Ссылку объекта Работая с объектами, при обычном присваивании мы и так копируем Ссылки объектов (номерки от курток) вместо копирования самих объектов. Возникает вопрос: зачем здесь вообще Ссылки, если мы и так работаем со Ссылками объектов? Для ответа на вопрос рассмотрим функцию:
Другой пример:
Итак, Ссылка на Ссылку объекта имеет право на существование, если Вы четко понимаете, что делаете.
19
|
13208 / 6596 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
|
|||||||||||||||||||||
04.09.2010, 17:53 [ТС] | 4 | ||||||||||||||||||||
Копирование при записи (Copy on write)
Копирование при записи напрямую не связано со ссылками в PHP. Однако с этим явлением Вы косвенно сталкиваетесь очень часто не только в PHP, но и во многих других языках программирования. Источник проблемы Предположим, есть код:
А что, если функция не будет изменять значение переданного аргумента? Напрашивается вывод, что строка будет копироваться впустую и, таким образом, вхолостую тратить ресурсы. Вот здесь-то и вступает в силу оптимизация по имени Копирование при записи. Как это работает? Суть этой оптимизации очень простая: реальное копирование данных выполняется только тогда, когда это действительно необходимо (когда формальную копию нужно изменить). Чтобы понять, как она работает, воспользуется PHP функцией memory_get_usage(), которая возвращает объем памяти, занимаемой интерпретатором PHP.
Причем здесь ссылки? Предоложим, что Вы создаете функцию, которая должна принимать в аргумент строку (или массив), которая теоритически может иметь достаточно большой объем. Сама функция не изменяет переданную строку, а использует ее только для чтения. Если бы Вы задумались об оптимизации, чтобы избежать холостого копирования (о котором говорилось выше), и если бы Вы не знали о существовании копирования при записи, то наверняка Вы бы в своей функции определили аргумент для передачи по ссылке.
28
|
04.09.2010, 17:53 | |
04.09.2010, 17:53 | |
Помогаю со студенческими работами здесь
4
Ссылки PHP PHP и HTML ссылки Не работают некоторые запросы в БД из PHP через AJAX с HTML страницы Как работают ссылки типа <a href=news.php?1> </a> Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |