root.elima.ru
Мертвечина
Статьи и книгиИнтернет-технологии и сетевое программирование

Удобная штука – сессии

В этом выпуске мы поговорим о таком важном механизме, как сессии. Встроенная поддержка сессий появилась в PHP начиная с 4-ой версии (до этого сессии были реализованы в виде внешней библиотеки), поэтому данный материал в основном будет полезен только пользователям этой версии языка. Но о том, что наши материалы будут ориентированы именно на PHP4, мы предупреждали в первом выпуске.

Сессии в PHP

Сессии – это механизм, который позволит вам создавать и использовать переменные, сохраняющие свое значение в течение всего времени работы пользователя с вашим сайтом. При этом у каждого пользователя вашего сайта эти переменные будут собственными, т.е. их область видимости (variable scope) распространяется на все время нахождения на сайте конкретного пользователя, причем для каждого захода пользователя на ваш сайт эти переменные будут различными. Говоря проще, эти переменные принадлежат конкретной сессии работы конкретного пользователя с вашим сайтом (отсюда и название механизма – сессии).

Для того, чтобы понять всю важность этого механизма необходимо понимать отличие в принципах построения обычных программ, выполняющихся на локальной машине пользователя и систем "клиент-сервер", к которым относятся web-сайты. Ниже я постараюсь вкратце объяснить наиболее важные моменты.

Системы "клиент-сервер"

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

Эта схема работает следующим образом: пользователь, через браузер посылает запрос на сервер. На стороне сервера запрос принимает программа web-сервера (в большинстве случаев – Apache), анализирует запрос и, в нашем случае, вызывает PHP для обработки этого запроса. PHP выполняет ваш скрипт, задачей которого является генерация страницы, соответствующей полученному запросу. По завершении работы PHP передает сгенерированную страницу web-серверу, который отсылает ее обратно на машину клиента как результат обработки его запроса.

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

В основе всего механизма сессий лежит решение задачи об идентификации того, от кого именно пришел запрос на сервер. Если это будет точно известно, то уже не возникнет большой проблемы в том, чтобы предоставить скрипту информацию, относящуюся именно к этому конкретному пользователю. Данная задача решается путем присвоения каждой сессии уникального идентификатора SID (Session IDentifier), который создается в тот момент, когда пользователь заходит на сайт, и уничтожается в момент, когда пользователь уходит с сайта. Этот идентификатор передается на сервер вместе с каждым запросом со стороны клиента и возвращается на машину клиента вместе с результатами обработки запроса. Алгоритм генерации SID (а в PHP в качестве идентификатора сессии используется т.н. GUID (Global Unique IDentifier)) позволяет гарантировать его уникальность, поэтому исключена возможность того, что две сессии будут иметь один и тот же идентификатор сессии.

PHP может использовать два различных механизма в качестве "транспортного средства" для передачи SID:

Cookies – это, конечно, более удобный способ передачи идентификатора. При этом SID сохраняется "внутри" браузера и остается незаметным для пользователя. Но поддержка cookies – это необязательное условие для браузера, она может отсутствовать или быть отключена у кого-то из посетителей, поэтому в общем случае полагаться на них нельзя. В этом случае можно использовать менее "красивый", но более надежный способ – передачу SID через параметр query string. PHP имеет возможность автоматически добавлять SID ко всем линкам в генерируемых HTML страницах, поэтому вам, как правило, не нужно будет заботиться о том, чтобы добавлять этот идентификатор к каждому линку вручную. Если же вы по каким-либо причинам хотите сами передавать идентификатор сессии – вы всегда можете получить его из константы SID или из функции session_id().

Создание и использование сессионных переменных

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

session_start();

Пусть вас не смущает вопрос: "Что будет, если я вызову эту функцию дважды?", все будет в порядке. Вам необходимо вызывать эту функцию на каждой странице, на которой вам необходимо использовать сессионные переменные. Кроме того, если вы часто используете сессионные переменные в своих программах, вы можете просто изменить настройки PHP таким образом, чтобы сессии инициализировались автоматически. Для этого исправьте следующую строчку в php.ini:

session.auto_start = 1

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

session_register('var1','var2',...);

В качестве параметров функции передаются имена сессионных переменных, которые необходимо создать. Обратите внимание на то, что передаются именно имена, а не сами переменные, как можно подумать. Необходимо помнить об этом, дабы избежать ошибок.

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

Способ обращения к сессионным переменным зависит от настроек в файле php.ini. Если register_globals включен, то обращение к сессионной переменной по синтаксису ничем не будет отличаться от обращения к обычной переменной:

session_register('myVar');


$myVar = 5;

Если же он выключен – то обращаться к сессионным переменным необходимо через глобальный массив $HTTP_SESSION_VARS:

session_register('myVar');


$HTTP_SESSION_VARS['myVar'] = 5;

Кроме того в php.ini есть и множество других настроек, касающихся сессий, но вам, в большинстве случаев, придется использовать лишь несколько:

session.save_path

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

session.use_cookies

Определяет, необходимо ли использовать cookies для хранения SID. Если значение этого параметра установлено в "да" (1, On, Yes, True), то будут использоваться cookies, если в "нет" (0, Off, No, False) – то SID будет передаваться через параметр query string.

session.auto_start

Если занчение этого параметра установлено в "да", то сессия будет каждый раз создаваться автоматически, в противном случае вам необходимо будет каждый каз инициализировать ее вручную, вызывая функцию session_init()

session.cookie_lifetime

Время (в секундах), в течении которого будет сохраняться в браузере cookie, содержащая SID. Если значение этого параметра установлено в 0, то сессия будет сохраняться до тех пор, пока пользователь не закрот окно браузера. Если же значение задано, то по истечение заданного промежутка cookie будет удалена и сессия будет считаться закрытой. В некоторых случаях (например при написании административных программ или других частей сайта, доступ к которым должен быть ограничен) это бывает очень полезно.

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

Для того, чтобы проиллюстрировать использование сессионных переменных – приведу пример двух очень простых страничек:

page1.php

<?php
session_start();
session_register('myVar');

$myVar = 'It works! This is value of session variable';
?>
<html>
<a href="page2.php">click here</a>
</html>

page2.php

<?php
session_start();
echo $myVar;
?>

Если все работает правильно, то при клике на ссылку на первой страничке вы должны увидеть надпись:

It works! This is value of session variable

Александр Грималовский