Чат Telegram
Группа ВКонтакте
Сессии в PHP

Сессии в PHP

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

Сеансы (sessions) позволяют разрешить эту проблему, обеспечивая поддержку данных между страницами на протяжении всего времени посещения пользователем вашего сайта. В рамках каждого сеанса могут быть задействованы многие переменные, которые будут храниться на протяжении всего сеанса. Сервер следит за сеансами пользователей, назначая им уникальные идентификаторы, которые генерируются сервером в момент открытия сеанса. Этот идентификатор называется идентификатором сеанса (session identifier) и должен передаваться на сервер каждый раз, когда после начала сеанса запрашивается очередная страница.

Рисунок ниже иллюстрирует порядок взаимодействий между браузером клиента и веб-сервером в рамках сеанса:
Схема работы сеансов (сессий) пользователя

Информация о сеансах хранится на стороне сервера. Переменные сеанса сохраняются в файле, в сериализованном виде. Когда переменная сериализуется (преобразуется в последовательную форму), в файл записывается имя переменной, тип и значение в виде последовательной строки. В UNIX-подобных операционных системах этот файл обычно сохраняется в файловой системе /tmp (временная файловая система).

Интерпретатор PHP фактически не создает запись о сеансе, пока переменной сеанса не будет присвоено значение. Таким образом, при отсутствии каких-либо значений сеанс в действительности ничего не делает.

Браузер отправляет идентификатор сеанса на сервер всякий раз, когда запрашивает очередную страницу. Идентификатор сеанса может передаваться через cookie (как показано на схеме) или в виде параметра URL. По умолчанию идентификатор передается через cookie, но поскольку есть вероятность, что пользователь запретил использование cookie в настройках своего браузера, мы также рассмотрим возможность передачи идентификатора сеанса в строке URL.

Необходимость в использовании средств поддержки сеансов

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

  • К проекту сайта предъявляется требование, чтобы по мере прохождения пользователя от одной страницы к другой содержимое страниц, развертываемых в браузере, изменялось в зависимости от того, какие страницы уже посетил пользователь (или от количества просмотренных страниц).
  • Требуется, чтобы в окне браузера пользователя отображались рекламные объявления, но каждое конкретное объявление не должно появляться больше одного раза в течение каждого сеанса.
  • На протяжении сеанса необходимо накапливать информацию обо всех действиях, осуществляемых пользователем. Например, в приключенческой игре нужно следить за количеством выигранных очков и завоеванного оружия, а на сайте электронной коммерции — за наполнением тележки для покупок.
  • Необходимо в целом проследить за тем, как пользователи перемещаются по страницам сайта, например, узнать, как они обычно переходят на ту или иную внутреннюю страницу, — ставят на ней закладку или всегда проходят весь путь от начальной страницы?

Использование сеансов

Чтобы начать сеанс, нужно добавить в начало PHP-сценария вызов функции session_start() – лишь после этого появится возможность сохранять и получать данные, принадлежащие сеансу. Функцию session_start() следует вызвать до вызова функции header() и вообще до того, как браузеру клиента будет отправлена хоть какая-нибудь информация, в противном случае сеанс может работать некорректно.

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

<?php
    session_start();
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Основы PHP</title>
</head>

<body>

<?php 

if (!isset($_SESSION['count_view']))
{
    echo '<h1>Вы в первый раз посещаете данную страницу.</h1>';
    $_SESSION['count_view'] = 1;
}
else
{
    ++$_SESSION['count_view'];
    echo '<h1>Количество посещений вами этой страницы за 1 сеанс: '
        .$_SESSION['count_view'].'</h1>';
}

?>

</body>
</html>

Завершение сеанса

Есть моменты, когда требуется преждевременно завершить сеанс. Например, если вы разместили на странице кнопку или гиперссылку выхода из системы. Выход из системы фактически означает завершение сеанса работы с пользователем. Завершают сеанс с помощью функции session_destroy(). Разумеется, сеанс предварительно должен быть открыт, чтобы было что завершать.

Имейте в виду: завершение сеанса не означает, что его переменные станут недоступными для текущего PHP-сценария. В примере ниже приведен простой сценарий, который закрывает сеанс, делая при этом его переменные недоступными для остальной части PHP-сценария:

<?php
session_start();

// Выполнить какие-либо действия в рамках сеанса
$_SESSION['username'] = 'Alex';

// Завершить сеанс работы с сайтом
session_destroy();

echo "В этот момент мы все еще можем увидеть значение имени пользователя: "
     .$_SESSION['username']."<br>";

// Уничтожить значение в массиве $_SESSION
unset($_SESSION['username']);

if (empty($_SESSION['username'])) 
{
    echo "Теперь переменная \$_SESSION['username'] является пустой";
}
?>

Результат работы сценария из примера приведен на рисунке:
Закрытие сеанса и удаление связанной переменной из массива $_SESSION

При закрытии сеанса его данные удаляются из файлов на стороне сервера. Чтобы удалить переменные сеанса, необходимо присвоить пустой массив суперглобальной переменной $_SESSION.

Функции поддержки сеанса

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

Общие сведения о функциях поддержки сеансов

Функция Описание
session_register() Принимает в качестве параметра строку и регистрирует переменную с именем, обозначенным этой строкой, например session_register('usemame'). Использование этой функции не рекомендуется по соображениям безопасности.
session_unregister() Принимает в качестве параметра строку с именем переменной и отменяет регистрацию соответствующей переменной в сеансе. Т.к. используется в связке с session_register(), не рекомендуется к использованию.
session_is_registered() Принимает строку с именем переменной и проверяет, зарегистрирована ли переменная с данным именем переменной в текущем сеансе. Т.к. используется в связке с session_register(), не рекомендуется к использованию.
session_unset() Вызывается без параметров и освобождает все переменные в сеансе. Может приводить к опасным последствиям, если используется в сочетании с массивом $_SESSION, вместо нее рекомендуется использовать функцию unset()
session_write_close() Позволяет закрыть сеанс вручную и освободить блокировки записи, установленные на файлах данных. Необходимость в использовании этой функции возникает во время работы со страничными блоками; в некоторых ситуациях, связанных с кластеризацией; а также после выполнения действий, не позволяющих интерпретатору PHP обнаружить окончание сеанса (как в случае перенаправления)
session_name() Если вызов происходит без параметров, возвращает строку с именем текущего сеанса. По умолчанию это имя обычно представляет собой 'PHPSESSID'. После вызова с одним строковым параметром функция session_name() устанавливает текущее имя сеанса, равное этой строке. Имя сеанса используется в качестве ключа для поиска идентификатора сеанса в cookie-файле и параметрах GET/POST, поэтому успешный поиск идентификатора возможен, только если имя сеанса оставалось одним и тем же и на этапе сериализации, и на этапе выборки значений переменных сеанса. Следует отметить, что само изменение имени сеанса имеет смысл лишь в том случае, если требуется различать типы сеансов, обслуживаемых одним и тем же веб-сервером (например, когда используется несколько сайтов, на каждом из которых отслеживаются сеансы). Имя сеанса переустанавливается и принимает предусмотренное по умолчанию значение после каждого вызова сценария на выполнение, поэтому операция изменения имени должна предусматриваться в каждом сценарии, в котором используется имя, и осуществляться до вызова для работы в сеансе любых других функций
session_save_path() Возвращает (или устанавливает, если задан параметр) путь к каталогу, в котором должны быть записаны файлы с информацией связывания переменных сеансов (как правило, этот каталог в системах типа Unix принимает по умолчанию имя /tmp). Каталог должен существовать и иметь соответствующие значения прав доступа, для того, чтобы интерпретатор PHP мог записывать в нем файлы.
session_id() После вызова без параметров возвращает строку, которая является уникальным ключом, соответствующим конкретному сеансу. Если задан строковый параметр, устанавливает значение идентификатора сеанса, равное этой строке
session_regenerate_id() Не принимает параметров и задает новый идентификатор сеанса, в случае необходимости устанавливая новый cookie-файл. В случае успешного завершения возвращает значение true, а в случае неудачи возвращает false. В отличие от session_id() эта функция не возвращает строку с новым действующим идентификатором
session_encode() Возвращает строку, в которой закодировано состояние текущего сеанса, подходящую для использования в функции string_decode(). Полученная строка может служить для сохранения данных о сеансе (например, посредством записи закодированной строки в файл или базу данных) и последующего восстановления по истечении определенного времени
session_decode() Принимает в качестве параметра закодированную строку, которая получена с помощью функции session_encode(), и восстанавливает состояние сеанса, преобразуя результаты связывания переменных сеанса в связывания переменных страницы, по такому принципу, как и функция session_start()
session_get_cookie_params() Возвращает массив с текущими данными cookie-файла сеанса: lifetime (срок существования, измеряется в секундах, которые должны пройти до истечения срока существования; 0 означает, что срок существования не регламентируется), path (путь, для которого cookie-файл является допустимым), domain (домен, для которого cookie-файл является допустимым), secure (степень защищенности, которая показывает, действительно ли данный cookie-файл следует передавать только по соединениям SSL). Эти параметры обычно устанавливаются в файле php.ini, но могут быть изменены для одного сценария с помощью функции session_set_cookie_params()
session_set_cookie_params() Принимает четыре параметра указанные в описании функции session_get_cookie_params(). В параметре path следует обязательно предусмотреть заключительную косую черту.
loader
Об авторе проекта
Артём Ивашкевич
Артём Ивашкевич
Занимаюсь программированием более трех лет. В свободное время обучаю программированию на PHP других людей, потому что мне это нравится. Если вы интересуетесь темой IT и хотели бы стать разработчиком, рекомендую прочитать статью о том, как я стал программистом.
Комментарии (0)
Новый комментарий


Логические задачи с собеседований