
3. Характеристика сессий
В самом начале мы описали персональную область данных, которой так не хватает веб-программисту, чтобы хранить что-либо. Далее мы установили, что PHP надо только сообщить названия переменных. После этого РНР присвоит всем посетителям идентификаторы (число 128 бит), которое невозможно подделать, откроет на диске файл, названный аналогично номеру сессии для хранения информации. Данные там запакованы с помощью функции сериализации, т.е. наипростейшим способом. Чтобы наш сайт успешно работал, мы должны позаботиться о передаче идентификатора от запроса к запросу. Делать это можно разными путями. БОльшую часть работы РНР делает сам.
Рассмотрим поведение РНР по умолчанию и что требуется от программиста в особых случаях (например, если cookiesу посетителя отключены). Поведение РНР при нестандартных параметрах описано ниже.
Представьте, что посетитель обратился к одной из страниц Вашего сайта. РНР прочел файлы конфигурации. Интерпретатор РНР начинает выполнять РНР-файл. Если он там не встретит команду session_register() или session_start(), то никакие сессии работать не будут. Если бы РНР обнаружил параметр настройки php.inisession.auto_start равный 1, то сессии стартовали бы без нашей команды (по умолчанию данный параметр содержит 0 - выключено).
В нашей программе (мы работаем с сессиями) эти строчки будут одними из первых, что обработаются РНР-процессором. Поэтому можно считать, что поддержка сессии запустится при старте скрипта.
Что входит в понятие запуск сессий.РНР пытается выяснить, новый это посетитель или нет. Если новый - надо выдать ему новое случайное число и создать файл под хранение сессии, если старый - взять его идентификатор и извлечь из соответствующего файла переменные сессии. Возможно, посетитель будет иметь номер несуществующей сессии. Тогда он приравнивается к новому посетителю.
Алгоритм извлечения идентификатора. Из настроек сервера известно, что имя переменной, хранящей идентификатор - PHPSESSID (можно задать произвольное).
Если идентификатор будет найден в cookies, то пользователь считается идентифицированным и используетсяcookies: повторноcookiesне устанавливается, URL не подвергаются автозамене (о автозамене чуть ниже).
Если идентификатор найден в URL (GET-запрос) или в POST-запросе и не найден в cookies, то пользователь считается идентифицированным и не использующимcookies:cookiesвыставляется (на всякий случай), URL проходят автозамену, чтобы вставить в них идентификатор.
Если идентификатор не найден ни в cookies, ни в URL, то пользователь считается новым, использует ли онcookies– не известно, происходит выделение нового случайного идетификатора и установка вcookies, автозамена всех URL.
Таким образом, можно определить поведение РНР: при первом визите человека на Ваш сайт РНР не находит идентификатора; он устанавливает cookiesи производит автозамену всех URL и форм. При втором и последующем обращениях, если у человека включеныcookies, то РНР будет каждый раз получать идентификатор изcookiesи, соответственно, не будет производить повторной установкиcookiesили автозаменять URL. Если при повторном посещении РНР обнаружит идентификатор только в URL, то РНР будет и далее пытаться установитьcookiesи производить автозамену. Все это следует из приведенных выше 3-х правил.
Алгоритм установки cookies.После завершения работы первого алгоритма получается, что все пользователи становятся идентифицированными с каким-то номером - старым или новым. Если в предыдущей проверке выполнились 2 или 3 варианты, по РНР устанавливаетcookies. Если выполнился вариант 1 -cookiesповторно не отсылается.cookiesустанавливать можно только до вывода на экран какого-либо текста. Поэтому и надо писать команду session_start() в самом начале программы. Хотя можно применить буферизацию вывода, установив вphp.inioutput_buffering в on. Тогда Вы сможете стартовать сессии в любом месте программы, ставитьcookiesи писать где угодно информацию в заголовок страницы (с помощью функции Header()).
Алгоритм автозамены всех ссылок и форм.После того, как РНР-программа закончит работу, но до вывода результата браузеру, происходит автозамена ссылок. Вернее, РНР решает, нужно ли ее производить. Если из вышеприведенных 3-х вариантов срабатывают 2-й или 3-й (либо посетитель новый, либо у него намеренно отключеныcookies), то РНР производит автозамену. Автозамена всех ссылок такого типа:
БЫЛО: click here
СТАЛО: click here
Подобным образом ПХП пытается вставить идентификаторы во все формы GET или POST запроса:
Данная автозамена происходит без Вашего участия, РНР сам решает, когда нужно заменять и сам пытается встроить идентификатор посетителя, чтобы не потерять его. Таким образом, если Вы будете делать страницы, содержащие ссылки и формы, РНР постарается все позаменять. Однако, если Вы постараетесь ему помешать, например, вставляя HTML-теги с помощью функции javascript:document.write(), то РНР явно не станет анализировать эти скрипты. Короче говоря, РНР не гарантирует вам 100%-ной замены всех ссылок и форм, но работает он очень хорошо.
Чтобы автоматическая замена URL работала, убедитесь, что РНР скомпилирован с опцией --enable-trans-id. Если на Вашем сайте не происходит автозамены - перекомпилируйте свой РНР. Обычно РНР компилируют с минимальным количеством параметров и указанного параметра там нет. Если Ваш сервер очень нагружен, по подумайте, стоит ли вообще включать автозамену URL (скорее всего Вы можете себе это позволить, т.к. на подавляющем большинстве серверов процессор в среднем загружен только на 5-10%).
Обратите внимание, что все, связанное с автозаменой, нужно только для пользователей с отключеными cookes. Поэтому, если Вы не хотите рассматривать вариант отключенныхcookies, соответственно Вам не нужен режим автозамены.
Если Вы хотите поддерживать работу сайта с отключенными cookies, но не хотите, чтобы РНР автоматически заменял ссылки и формы, либо если РНР на какой-то конкретной ссылке/форме не вставляет идентификатор, проделывайте это вручную. Это очень просто. Для начала определим новую константу SIDFORM (после session_start()):
define ("SIDFORM","");
Представим, что у нас есть ссылки и формы (еще бывают фреймы и теги типа AREA, где все происходит аналогично). С помощью двух констант SID (определена в РНР) и SIDFORM (придумали сами), переработаем текст:
------------------БЫЛО (РНР-файл)------------------
Ссылка: click here ...
Форма:
....
------------------МЫ ЗАМЕНЯЕМ НА (новая версия РНР-файла)------------------
Ссылка: >click here ....
Форма:
....
------------------РЕЗУЛЬТАТ ВЫПОЛНЕНИЯ (это получит браузер)------------------
Ссылка: click here ....
Форма:
....
Тоже самое будет и в РНР-варианте: echo "<a href=test.php?e=2>click here</a>"; надо заменить на echo "<a href=test.php?e=2&".SID.">click here</a>";
Обратите внимание, что SID - это константа. И если вы хотите иметь переменную $SID, то просто напишите в начале программы $SID=SID; (после старта сессий).
Итак, подведем итог автозамене. Если Вы не хотите вставлять идентификаторы - полагайтесь на РНР, который постарается все ссылки заменить. Если вы хотите 100%-ной надежности того, что все смогут использовать Ваш сайт и ни один пользователь ни на одной старнице случайно не потеряет сессию, то прибавляйте к каждой форме и ссылке по небольшой константе (их можно назвать очень коротко, типа "X" и "Y").