Что такое сессия в программировании
Перейти к содержимому

Что такое сессия в программировании

  • автор:

Сессии. Подробное описание работы и объяснение механизма.

Введение
Сессии — это на самом деле очень просто.
Надо только понимать, для чего они нужны и как устроены.
Ответим сначала на первый вопрос.
Как показано в соответствующем разделе этого FAQ, веб-сервер не поддерживает постоянного соединения с клиентом, и каждый запрос обрабатывается, как новый, безо всякой связи с предыдущими.
То есть, нельзя ни отследить запросы от одного и того же посетителя, ни сохранить для него переменные между просмотрами отдельных страниц. Вот для решения этих двух задач и были изобретены сессии.
Собственно, сессии, если в двух словах — это механизм, позволяющий однозначно идентифицировать браузер и создающий для этого браузера файл на сервере, в котором хранятся переменные сеанса.

Подробно расписывать нужду в таком механизме я не буду. Это такие хрестоматийнык случаи, как корзина покупок в е-магазине, авторизация, а так же, и не совсем тривиальные проблемы, такие, например, как защита интерактивных частей сайта от спама.

В принципе, довольно несложно сделать собственный аналог сессий, не такой функциональный, как встроенный в PHP, но похожий по сути. На куках и базе данных.
При запросе скрипта смотрим, пришла ли кука с определенным именем. Если куки нет, то ставим ее и записываем в базу новую строку с данными пользователя. Если кука есть, то читаем из базы данные. Еще одним запросом удаляем из базы старые записи и вот у нас готов механизм сессий. Совсем несложно. Но есть некоторые нюансы, которые делают предпочтительным использование именно встроенного механизма сессий.

Как устроены, и как работают сессии?
Для начала надо как-то идентифицировать браузер. Для этого надо выдать ему уникальный идентификатор и попросить передавать его с каждым запросом. Стыдно признаться, но когда я впервые узнал о сессиях, я думал, что это какой-то особый механизм, некий новый способ общения браузера с сервером — «сессии». Что идентификатор сессии передается каким-то особым образом. Разочарование было жестоким.
Сессии используют стандартные, хорошо известные способы передачи данных. Собственно, других-то просто и нет.
Идентификатор — это обычная переменная. По умолчанию ее имя — PHPSESSID.
Задача PHP отправить ее браузеру, чтобы тот вернул ее со следующим запросом. Из уже упоминавшегося раздела FAQ ясно, что переменную можно передать только двумя способами: в куках или POST/GET запросом.
PHP использует оба варианта.
За это отвечают две настройки в php.ini:
session.use_cookies — если равно 1, то PHP передает идентификатор в куках, если 0 — то нет.
session.use_trans_sid если равно 1, то PHP передает его, добавляя к URL и формам, если 0 — то нет.
Менять эти и другие параметры сессий можно так же, как и другие настройки PHP — в файле php.ini, а так же с помощью команды ini_set() или в файлах настройки веб-сервера

Если включена только первая, то при старте сессии (при каждом вызове session_start() ) клиенту устанавливается кука. Браузер исправно при каждом следующем запросе эту куку возвращает и PHP имеет идентификатор сессии. Проблемы начинаются, если браузер куки не возвращает. В этом случае, не получая куки с идентификатором, PHP будет все время стартовать новую сессию, и механизм работать не будет.

Теоретически, в наших с вами самодельных сессиях на куках и базе, можно самому, руками приписать ко всем ссылками передачу ид — и тогда наши собственные сессии будут работать независимо от кук. Но, согласитесь — приятнее, когда эту работу делает кто-то другой? 😉

По умолчанию в последних версиях PHP включены обе опции. Как PHP поступает в этом случае? Кука выставляется всегда. А ссылки автодополняются только если РНР не обнаружил куку с идентификатором сессии. Когда пользователь в првый раз за этот сеанс заходит на сайт, ему ставится кука, и дополняются ссылки. При следующем запросе, если куки поддерживаются, PHP видит куку и перестает дополнять ссылки. Если куки не работают, то PHP продолжает исправно добавлять ид к ссылкам, и сессия не теряется.
Пользователи, у которых работают куки, увидят длинную ссылку с ид только один раз.

Фух. С передачей идентификатора закончили.
Теперь осталось привязать к нему файл с данными на стороне сервера.
PHP это сделает за нас. Достаточно просто написать
session_start();
$_SESSION[‘test’]=’Hello world!’;
И PHP запишет в файл, связанный с этой сессией, переменную test.
Здесь очень важное замечание.
Массив $_SESSION — особенный.
В нем, собственно, и находятся переменные, которые мы ходим сделать доступными в различных скриптах.
Чтобы поместить переменную в сессию, достаточно присвоить ее элементу массива $_SESSION.
Чтобы получить ее значение — достаточно обратиться к тому же элементу. Пример будет чуть ниже.

Cборкой мусора — удалением устаревших файлов PHP тоже занимается сам. Как и кодированием данных и кучей всяких других нужных вещей. В результате этой заботы работа с сессиями оказывается очень простой.
Вот мы, собственно, и подошли к примеру работы сессий.
Пример очень маленький:
session_start();
if (!isset($_SESSION[‘counter’])) $_SESSION[‘counter’]=0;
echo «Вы обновили эту страницу «.$_SESSION[‘counter’]++.» раз. «;
echo «
обновить»;
?>
Мы проверяем, есть ли у нас в сессии переменная counter, если нет, то создаем ее со значением 0, а дальше выводим ее значение и увеличиваем на единицу. Увеличенное значение запишется в сессию, и при следующем вызове скрипта переменная будет иметь значение 1, и так далее.
Все очень просто.

Для того, чтобы иметь доступ к переменным сессии на любых страницах сайта, надо написать ТОЛЬКО ОДНУ(!) строчку в самом начале КАЖДОГО файла, в котором нам нужны сессии:
session_start();
И далее обращаться к элементам массива $_SESSION. Например, проверка авторизации будет выглядеть примерно так:
session_start();
if ($_SESSION[‘authorized’]<>1) header(«Location: /auth.php»);
exit;
>

Удаление переменных из сессии.
Если у вас register_globals=off , то достаточно написать
unset($_SESSION[‘var’]);
Если же нет, то тогда рядом с ней надо написать
session_unregister(‘var’);

Область применения.
Очень важно понимать, для чего сессии стоит использовать, а для чего — нет.

Во-первых, помните, что сессии можно применять только тогда, когда они нужны самому пользователю, а не для того, чтобы чинить ему препятствия. Ведь он в любой момент может избавиться от идентификатора!
Скажем, при проверке на то, что заполняет форму человек, а не скрипт, пользователь сам заинтересован в том, чтобы сессия работала — иначе он не сможет отправить форму! А вот для ограничения количества запросов к скрипту сессия уже не годится — злонамеренный скрипт просто не будет возвращать идентификатор.

Во-вторых. Важно четко себе представлять тот факт, что сессия — это сеанс работы с сайтом, так как его понимает человек. Пришел, поработал, закрыл браузер — сессия завершилась. Как сеанс в кино. Хочешь посмотреть еще один – покупай новый билет. Стартуй новый сеанс. Этому есть и техническое объяснение. Гарантированно механизм сессий работает только именно до закрытия браузера. Ведь у клиента могут не работать куки, а в этом случае, естественно, все дополненные идентификатором ссылки пропадут с его закрытием.
Правда, сессия может пропасть и без закрытия браузера. В силу ограничений, рассмотренных в самом главном разделе этого FAQ, механизм сессий не может определить тот момент, когда пользователь закрыл браузер. Для этого используется таймаут – заранее определенное время, по истечении которого мы считаем, что пользователь ушел с сайта. По умолчанию этот параметр равен 24 минутам.
Если вы хотите сохранять пользовательскую информацию на более длительный срок, то используйте куки и, если надо — базу данных на сервере. В частности, именно так работают все популярные системы авторизации:
— по факту идентификации пользователя стартует сессия и признак авторизованности передается в ней.
— Если надо «запомнить» пользователя, то ему ставится кука, его идентифицирующая.
— При следующем заходе пользователя на сайт, для того, чтобы авторизоваться, он должен либо ввести пароль, либо система сама его опознает по поставленной ранее куке, и стартует сессию. Новую сессию, а не продолжая старую.

В-третьих, не стоит стартовать сессии без разбору, каждому входящему на сайт. Это создаст совершенно лишнюю нагрузку. Не используйте сессии по пустякам – к примеру, в счетчиках. То, что спайлог называет сессиями, считается, конечно же, на основе статистики заходов, а не с помощью механизма сессий, аналогичного пхп-шному.
К тому же, возьмем поисковик, который индексирует ваш сайт. Если поисковый робот не поддерживает куки, то пхп по умолчанию будет поставлять к ссылкам PHPSESSID, что — согласистесь — может не сильно понравится поисковику, который, по слухам, и так-то динамические ссылки не жалует, а тут вообще при каждом заходе — новый адрес!
Если сессии используются для ограничения доступа к закрытому разделу сайта, то все просто поисковик и не должен его индексировать.
Если же приходится показывать одну и ту же страницу как авторизованным, так и не авторизованным пользователям, то тут поможет такой трюк – стартовать сессию только тем, кто ввел пароль, или тем, у кого уже стартовала сессия.
Для этого в начало каждой страницы вместо просто session_start() пишем
if (isset($_REQUEST[session_name()])) session_start();
таким образом, Мы стартуем сессию только тем, кто прислал идентификатор.
Соответственно, надо еще в первый раз отправить его пользователю – в момент авторизации.
Если имя и проль верные – пишем session_start() !

Самыми распространенными ошибками, которые выдает РНР при попытке работать с сессиями, являются такие:
Две из них,
Warning: Cannot send session cookie — headers already sent
Warning: Cannot send session cache limiter — headers already sent
вызваны одной и той же причиной, решение описано в этом факе здесь
Третья,
Warning: open(/tmp\sess_SID, O_RDWR) failed: No such file or directory (2) in full_script_path on line number (ранее она выглядела, как Warning: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/tmp) ),
если перевести ее с английского, подробно объясняет проблему: недоступен указанный в php.ini путь к каталогу, в который пишутся файлы сессий. Эту ошибку исправить проще всего. Просто прописать каталог, который существует, и доступен на запись, например,
session.save_path = c:\windows\temp
И не забыть перезагрузить апач после этого.

Как выясняется, сообразительность людская не имеет пределов, и поэтому я вынужден пояснить:
сообщение о третьей ошибке (невозможно найти каталог) НЕИЗБЕЖНО приведет к появлению первых двух, поскольку сообщение об ошибке — это вывод в браузер и после него заголовками пользоваться нельзя. Поэтому не спешите искать преждевременный вывод, а сначала пропишите правильный путь!

Следующей по распространенности проблемой при работе с сессиями является тяжелое наследие register_globals. НЕ давайте переменным скрипта имена, совпадающие с индексами массива $_SESSION!
При register_globals=on значения будут перезаписывать друг друга, и вы запутаетесь.
А при register_globals=off появится другая ошибка: «Your script possibly relies on a session side-effect which existed until PHP 4.2.3.», в случае, если в скрипте есть переменная сессии не имеющая значения, и глобальная переменная с тем же именем. Чтобы от неё избавиться, надо всегда инициализировать переменные перед использованием (или хотя бы проверять на существование) и не давать глобальным переменным имена, совпадающие с индексами массива $_SESSION.

Если не работает, но и никаких сообщений не выводится, то добавьте в самое начало скрипта две строчки, отвечающие за вывод ВСЕХ ошибок на экран — вполне возможно, что ошибки есть, но вы их просто не видите.
ini_set(‘display_errors’,1);
error_reporting(E_ALL);
или смотрите ошибки в error_log. Вообще, тема отображения сообщений об ошибках выходит за рамки данной статьи, поэтому просто убедитесь хотя бы, что вы можете их видеть. Чуть продробнее о поиске ошибок можно прочитать в этом разделе.

Если этот пример не заработает, то проблема либо в банальных опечатках (половина «проблем» с сессиями происходит от неправильно написанного имени переменной), либо в слишком старой версии PHP: поддержка сессий появилась в версии 4.0, а массив $_SESSION — в 4.1 (До этого использовался $HTTP_SESSION_VARS ).
Если же заработает — то проблема в куках. Отслеживайте — что за куку ставит сервер браузеру, возвращает ли браузер ее. Искать очень полезно, просматривая просматривая обмен HTTP-заголовками между браузером и сервером.
Объяснение принципа работы кук выходит за рамки этого и так уж слишком большого текста, но хотя бы убедитесь, что сервер куку с идентификатором посылает, а браузер — возвращает. И при этом идентификаторы совпадают друг с другом =)
Установка куки должна выглядеть, как
Set-Cookie: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6;
или как
Set-Cookie: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6; path=/
(если вы запрашиваете скрипт не из корневого каталога)
Ответ сервера должен выглядеть, как
Cookie: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6
либо
Cookie: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6; b=b
если браузер возвращает другие куки, кроме идентификатора сессии.

Если браузер куки не возвращает — проверьте, работают ли куки вообще.
Убедитесь, что домен, к которому вы обращаетесь, имеет нормальное имя (в котором есть хотя бы одна точка и не содержится запрещенных символов, например подчеркивания) и почистите кэш браузера — это две основные причины, по которм куки могут не работать.

Если пример отсюда работает, а ваш собственный код — нет, то проблема, очевидно, не в сессиях, а в алгоритме. Ищите, где потеряли переменную, по шагам переносите пример отсюда, отлаживайте свой скрипт.

Еще одна проблема может возникнуть, если вы используете перенаправление через header или навигацию с помощью JavaScript.
Дело в том, что РНР автоматически дописывает идентификатор сессии только к ссылкам вида , но не делает этого для header-ов, яваскрипта, мета-тегов.
Поэтому надо добавлять идентификатор руками, например, так:
header(«Location: /script.php?».session_name().’=’.session_id());

Следует помнить, что пхп лочит файл сессии. То есть, если один ваш скрипт стартует сессию и долго выполняется, а другой пытается в это время стартовать её с тем же идентификатором, то он зависнет. Поэтому в долго выполняющихся скриптах следует стартовать сессию только тогда, когда она нужна, и тут же закрывать её, с помощью session_write_close()

Так же, весьма редкая, и совершенно непонятно, откуда появляющаяся, проблема бывает в том, что настройка session.save_handler имеет значение, отличное от files. Если это не так — исправляйте.

Безопасность
Безопасность сессий — тема обширная. Поэтому остановлюсь на нескольких основных моментах.
Самый хрестоматийный — не передавать идентификатор через адресную строку. Об этом написано даже в php.ini, но это ограничивает функциональность сессий. Если вы решите последовать этому совету, то кроме session.use_trans_sid = 0 не забудьте session.use_only_cookies = 1
Желательно привязывать сессию к IP адресу: таким образом, если идентификатор будет украден, то злодей все равно не сможет им воспользоваться в большинстве случаев.
Рекомендуется пользоваться директивой session.save_path, с помощью которой задать собственный каталог для сохранения файлов сессий. Это более безопасно, чем когда они хранятся в общем временном каталоге сервера по умолчанию.

Пример авторизации с помощью сессий
Проиллюстрируем все вышенаписанное небольшим примером:
создадим файл auth.php:
if (isset( $_POST [ ‘auth_name’ ]))
$sql = «SELECT * FROM users WHERE name=?s» ;
$row = $db -> getRow ( $sql , $_POST [ ‘auth_name’ ]);
if ( $row && password_verify ( $_POST [ ‘auth_pass’ ], $row [ ‘pass’ ])) $_SESSION [ ‘user_id’ ] = $row [ ‘id’ ];
>
header ( «Location: http://» . $_SERVER [ ‘HTTP_HOST’ ]. $_SERVER [ ‘REQUEST_URI’ ]);
exit;
>

if (isset( $_GET [ ‘action’ ]) AND $_GET [ ‘action’ ]== «logout» ) session_start ();
session_destroy ();
header ( «Location: http://» . $_SERVER [ ‘HTTP_HOST’ ]. «/» );
exit;
>

теперь достаточно написать во всех защищаемых скриптах строчку
require «auth.php»;
В данном примере предполагается, что сессия уже стартовала и соединение с БД создано, с использованием Класс для безопасной и удобной работы с MySQL. Также предполагается, что пароль хэширован с использованием рекомендованной функции password_hash .
Пример защищаемого файла:

Сессия — Веб-разработка на PHP

Сессия — это абстракция, созданная для удобной работы с индивидуальными пользователями. Она используется для идентификации пользователей и позволяет отличать их друг от друга. Например, аутентификация на сайтах построена поверх механизма сессии.

Сессии реализуются на уровне конкретных фреймворков и только в PHP сессии встроены в язык. Общий принцип работы сессии сводится к трем операциям:

  • Старт сессии. Так мы говорим системе, что хотим начать следить за пользователем. Во многих фреймворках эта операция выполняется неявно при попытке чтения или записи в сессию
  • Запись данных в сессию
  • Чтение данных из сессии

Старт сессии на техническом уровне означает установку специальной куки в браузер. Обычно эта кука содержит идентификатор сессии, который уникален для каждого пользователя.

Данные сессии могут храниться где угодно. Это зависит от конкретной реализации. В этом одно из ключевых отличий работы с пользователями напрямую через куки или через сессию.

Сессия — более высокоуровневая абстракция. Например, в PHP по умолчанию данные сессии хранятся в файлах. Из этого следует сразу два вывода:

  • Сессия ограничена только физическим пространством дисков
  • Данные хранятся на сервере, что безопаснее

Если этого недостаточно, например, серверов больше чем один, то буквально парой строк кода в конфигурации можно изменить тип хранилища с файлов на базу данных.

Также при работе с сессией не надо думать про имена кук, про сериализацию и десериализацию составных данных. Это происходит автоматически.

 // Операция идемпотентна. Не важно, была ли инициализирована сессия раньше, старт сессии выполняется всегда session_start(); if (!isset($_SESSION['count']))  $_SESSION['count'] = 0; > else  $_SESSION['count']++; > print_r($_SESSION['count']); 

Этот простой скрипт демонстрирует работу сессий в PHP. В отличие от остальных суперглобальных массивов для работы с HTTP массив $_SESSION — изменяемый. Всё, что добавится в него, автоматически попадает в сессию и сохраняется между запросами до тех пор, пока кука не удалится или не изменится.

Из примера выше видно, что сессия упрощает работу с пользователем. Также значением массива $_SESSION может быть любая составная структура, массив или объект. Механизм сессий автоматически беспокоится о сериализации и десереализации.

Внутри Slim нет особенного механизма для работы с сессиями, так как они не являются частью стандарта PSR-7. Работа с сессией происходит напрямую.

Перепишем наш пример добавления товаров в корзину, используя сессию:

 session_start(); $app->post('/cart-items', function ($request, $response)  // Информация о добавляемом товаре $item = $request->getParsedBodyParam('item'); // Добавление нового товара $_SESSION['cart'][] = $item; return $response->withRedirect('/'); >); 

По сравнению с версией на куках ушла значительная часть кода. Кодирование и декодирование в JSON, извлечение куки и перезапись куки.

Иногда возникает задача уничтожать сессию, например, при выполнении выхода из системы. Полное уничтожение сессии включает в себя три шага:

  • Обновление куки с установкой даты в прошлое
  • Обнуление массива $_SESSION — $_SESSION = []
  • Обнуление хранилища сессий — session_destroy()

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Наши выпускники работают в компаниях:

Все, что нужно знать о сессии на сайте

Под сессией принято понимать строго обозначенный промежуток времени, на протяжении которого пользователь пребывает на сайте. Все пользователи для входа в интернет используют специальные программы – браузеры. Идентификация пользователя в интернете осуществляется с учетом его персональных данных, речь идет о cookies-файлах и IP-адресе.

Протяженность сеанса пользователя на сайте определяется исходя из промежутка между первым и последним действием, совершенным им на сайте. Практика показывает, что в ходе измерения протяженности сеанса возникают трудности. В первую очередь это обусловлено отсутствием возможности постоянного контроля над временем просмотра страницы, на которую перешел пользователь по ссылке. На данный момент не существует программного обеспечения, способного выполнять такие задачи.Чтобы разобраться в том, что такое сессия на сайте, рассмотрим следующий пример:

  • Необходимо войти в любой браузер;
  • Пройти процедуру авторизации в двух аккаунтах на одном сервисе (напр., в аккаунтах Google). И тут возникают первые трудности, так как сервис не дает возможности находиться одновременно в двух аккаунтах и предлагает выбрать какой-то один;
  • Далее открываем другой браузер, при этом не выходим из первого. Пробуем зайти во второй аккаунт на сервисе;
  • На этот раз уведомление от сайта не появилось и пользователь может просматривать сайт и со второго аккаунта.

Сценарии сессии на сайте

Сессия как событие в сервисах аналитики применяется с целью наблюдения за поведением пользователей, посещающих сайт. Сессия напрямую взаимосвязана со следующими метриками:

  • Просмотр страницы;
  • Продолжительность сеанса;
  • Действия, совершенные пользователем, во время его пребывания на странице;
  • Вовлеченность трафика.

На данный момент сессия как событие характеризуется широкой областью применения, одним из вариантов ее использования могут быть следующие сценарии:

  • Обработка данных с последующим удалением персональных данных пользователей;
  • Анализ трафика на сайте;
  • Тестирование сервера или сайта.

В рамках данной статьи мы будем рассматривать сессию применительно к сайту и веб-аналитике. В данном случае сессия выступает в качестве инструмента для определения последовательности запросов, выполняемых пользователем.

Клиент и сервер. Практическая реализация распознавания запроса

Если рассматривать сессию с точки зрения отдельного события, то речь идет о совокупности запросов, отправляемых от лица клиента в момент его взаимодействия с хостом/сервером. Клиент может быть представлен не только в виде браузера, но и в виде поискового робота или веб-приложения. Хост в большинстве случаев – это сайт.

Сессия может включать в себя все запросы, совершенные клиентом на протяжении строго обозначенного промежутка времени.

Сервер самостоятельно классифицирует запросы, поступающие от клиента. Сейчас широко применяется идентификация запроса – cookies-файл, важно отметить, что помимо него существуют и другие варианты. В качестве примера можно рассмотреть идентификацию запросов клиента посредством обращения к параметрам запроса, MAC-адресу, что стало возможным благодаря расширенным HTTP-заголовкам.

Взаимодействие HTTP-протокола на протяжении сеанса
Процесс создания и завершения сеанса на сайте

Открытие сессии PHP обеспечивается за счет функции session_start(), которая осуществляет проверку открытых сессий и в случае их отсутствия, производит запуск этой функции. Оптимальное решение – это размещение вызова session_start() в начале страницы. Переменные сеанса находятся в суперглобальном ассоциативном массиве $_SESSION[]. Открытие сессии позволяет получить доступ к этим переменным.

Для удаления сессии задействуется функция session_destroy(). Посредством одного вызова можно осуществить удаление всех переменных сеанса. Для удаления одной переменной сессии рекомендуется обратиться к функции unset(), которая дает возможность произвести отключение необходимой переменной.

Заключение

Каждый сайт содержит в себе не только вход, но и выход, который представлен в виде специального сценария, его основной целевой задачей является комплексная очистка сессии, после этого пользователь попадает на главную страницу.

Если рассматривать сессию в ее взаимосвязи с сайтом, то речь идет о многоаспектном понятии. При этом на практике чаще оно используется в тех случаях, когда возникает необходимость в составлении отчетов веб-аналитики. Комплексное изучение сессии как события позволит увеличить эффективность анализа отчетов веб-аналитики.

Что такое сессии и как с ними работать в php

Протокол http, используемый для загрузки содержимого web-страниц, работает следующим образом: клиент присылает серверу http-запрос, сервер его обрабатывает и отправляет клиенту сформированный ответ. Всё, на этом общение закончено. Если нужны новые данные — клиент посылает новый запрос, а сервер присылает новый ответ и так далее.

При этом существует ряд задач, когда серверу для формирования ответа нужно понимать, присылал ли этот клиент какие-то http-запросы ранее и что происходило в процессе их обработки. Самый очевидный пример — авторизация. Скажем, клиент в очередном http-запросе запрашивает какую-то страницу личного кабинета. Что делать серверу? Если клиент авторизован (ранее присылал правильные данные для авторизации), то нужно ему эту страницу показать, а если не авторизован — то не нужно. А как узнать, авторизован пользователь или не авторизован? Значит нужно где-то хранить результаты выполнения предыдущих http-запросов.

Как раз для таких случаев и придумали сессии, — специальный механизм, позволяющий серверу идентифицировать присылающих http-запросы клиентов, а также запоминать для этих клиентов различные данные.

Применительно к php можно сказать, что сессии — это механизм, позволяющий php-скрипту, обрабатывающему очередной http-запрос, сделать следующие вещи:

  1. понять, присылал ли этот же клиент http-запросы ранее
  2. восстановить сохранённые ранее для этого клиента данные
  3. сохранить данные для использования при обработке последующих http-запросов от этого клиента

Работают сессии следующим образом: сервер запоминает данные сессии (какие-то переменные) в специальном хранилище, которое подписывает сгенерированным уникальным идентификатором. Этот же идентификатор отправляется клиенту. При следующем http-запросе клиент присылает серверу полученный идентификатор, по которому сервер понимает от какого клиента пришёл запрос и с каким хранилищем ему работать (откуда восстанавливать данные и куда их сохранять).

Для работы с сессиями в php существуют специальные встроенные функции. Этих функций довольно много, основные я опишу ниже, а остальные можете посмотреть в документации, например вот здесь. Функции для работы с сессиями имеют большое количество всяких настроек, которые можно настраивать через конфиг php-сервера (файл php.ini), либо задавать в качестве опций непосредственно при вызове соответствующих функций. Многие настройки можно посмотреть через php_info().

По-умолчанию в качестве хранилища данных сессий php использует обычные файлы во временной папке. За это отвечает опция session.save_handler, которая по умолчанию установлена в значение files. При желании можно назначить свои собственные обработчики на связанные с сессиями события (старт, идентификация, сохранение данных и так далее) и хранить данные сессии как угодно и где угодно. Путь ко временной папке можно узнать при помощи функции sys_get_temp_dir().

Скрипт php может передать клиенту идентификатор созданного хранилища с помощью установки cookie или дописывая его к расположенным на загруженной странице адресам в качестве параметра GET-запроса. Выбор способа определяется настройками session.use_cookies, session_use_only_cookies и session_use_trans_sid. По умолчанию php настроен на использование только cookies (первые две настройки установлены в единицу, а последняя — в ноль). Используемое имя сессионной куки по-умолчанию — PHPSESSID.

Клиент может передать php-скрипту на сервере полученный ранее идентификатор любым способом (через cookie в заголовке запроса или указывая в качестве параметра GET-запроса) независимо от настроек. В случае с редиректом через header(‘Location: url’) куки не работают и идентификатор сессии должен быть передан на сервер в качестве параметра GET-запроса.

Сессионные переменные доступны в php скриптах через суперглобальный массив $_SESSION. В начале работы php-скрипта сессионные данные клиента загружаются из хранилища в этот массив, а когда выполнение скрипта завершается, — содержимое массива записывается назад в соответствующее хранилище.

Время жизни сессии определяется параметром session.gc_maxlifetime. По прошествии этого времени файлы данных сессии будут рассматриваться как мусор и могут быть удалены. Кроме того, можно задать время жизни отправляемой клиенту cookie (для этого используется параметр session.cookie_lifetime). По-умолчанию для session.cookie_lifetime установлено значение 0, которое означает, что кука будет актуальна до закрытия браузера (просроченные куки называются «протухшими»).

Далее давайте рассмотрим основные функции для работы с сессиями из php скриптов. Лучше всего установить какой-нибудь WAMP/WNMP комплект и попробовать проделать своими руками всё, о чём ниже пойдёт речь. Я обычно использую OpenServer + Firefox (в этом браузере удобнее всего вызывать отладчик — одной кнопкой F12).

Первая функция, которая нам понадобится, — это функция session_start(). Эта функция отвечает за то, чтобы по полученным в запросе данным определить, есть ли для отправившего запрос клиента активная сессия, и далее либо восстановить сохранённые данные сессии в суперглобальный массив $_SESSION (если сессия существует), либо стартовать новую сессию (если сессии для данного клиента нет). Очень удобно — просто вызываем в скрипте эту функцию и она сама разбарается, что дальше делать, — запускать новую сессию или восстанавливать старую.

Функция session_start() имеет довольно много опций, которые позволяют настраивать различные параметры сессии (имя, время жизни, безопасность и так далее). Подробности можно прочитать в документации. Если никакие опции не указывать, то будут использоваться настройки по-умолчанию, — из конфига php. Главное правило при использовании функции session_start() состоит в том, что она должна вызываться до какого-либо вывода (то есть до начала формирования тела ответа).

Вторая нужная функция — ini_set(). С помощью этой функции можно менять настройки php по-умолчанию. При этом значения в файле php.ini не изменяются, новые настройки действуют только для текущего скрипта и только до окончания его обработки.

Ещё одна нужная функция — session_name(). С помощью этой функции можно получить имя текущей сессии (если вызвать функцию без параметров) или изменить имя сессии (если указать в качестве параметра новое имя).

Следующая интересная функция называется session_unset(). Эта функция очищает все переменные массива $_SESSION. При этом сама сессия остаётся активной и данные из хранилища не стираются (они будут стёрты только когда завершится выполнение скрипта и php перепишет туда новое содержимое массива $_SESSION). При этом вы можете продолжить записывать в хранилище какие-то новые данные и они будут сохраняться.

Последняя функция, о которой я упомяну, — это функция session_destroy(). Она, в отличии от session_unset, как раз уничтожит все данные в хранилище, при этом не трогая текущее состояние массива $_SESSION. После вызова этой функции никакие новые данные сохранить в сессии уже не получится.

Вообще, как я уже сказал, функций довольно много, у большинства из них есть куча разных настроек, так что доку тут читать не перечитать.

Ну и, наконец, давайте проверим как это всё работает. Создайте в блокноте (кодировка utf-8 без BOM) и разместите в корневой папке своего локального сервера файл index.php следующего содержания:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *