PHP: использование механизмов Cookies и Session

Протокол HTTP является протоколом "без сохранения состояния". Это означает, что когда пользователь открывает сначала одну страницу сайта, а затем переходит на другую страницу этого же сайта, то основываясь только на средствах, предоставляемых протоколом HTTP невозможно установить, что оба запроса относятся к одному пользователю. Необходим механизм, при помощи которого можно было бы отслеживать информацию о пользователе в течение одного сеанса связи с Web-сайтом. В PHP такой механизм реализован при помощи сессий (session) и куки (cookies).

Сессии и куки предназначены для хранения сведений о пользователях при переходах между несколькими страницами. При использовании сессий данные сохраняются во временных файлах на сервере. Файлы с cookies хранятся на компьютере пользователя, и по запросу отсылаются браузером (browser) серверу.

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

COOKIES

Для установки Cookies используется функция SetCookie(). Для этой функции можно указать шесть параметров, первый из которых является обязательным:

name - задает имя (строк), закрепленное за Cookie;
value - определяет значение переменной (строка);
expire - время "жизни" переменной (целое число). Если данный параметр не указать, то Cookie будут "жить" до конца сессии, то есть до закрытия браузера. Если время указано, то, когда оно наступит, Cookie самоуничтожится.
path - путь к Cookie (строка);
domain - домен (строка). В качестве значения устанавливается имя хоста, с которого Cookie был установлен;
secure - передача Cookie через защищенное HTTPS-соединение.
Обычно используются только три первые параметра.

Пример установки Cookies:

<?php
// Устанавливаем Cookie до конца сессии:
SetCookie("Test","Value");
 
// Устанавливаем Cookie на один час после установки:
SetCookie("My_Cookie","Value",time()+3600);
?>

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

<?php
// Устанавливаем Cookie до конца сессии:
// В случае успешной установки Cookie, функция SetCookie возвращает TRUE:
if (SetCookie("Test","Value")) echo "<h3>Cookies успешно установлены!</h3>";
?>

Функция SetCookie() возвращает TRUE в случае успешной установки Cookie. В случае, если Cookie установить не удается SetCookie() возвратит FALSE и возможно, предупреждение (зависит от настроек PHP). Пример неудачной установки Cookie:

<?php
// Cookies установить не удастся, поскольку перед отправкой
// заголовка Cookie мы выводим в браузер строку 'Hello':
echo "Hello";
// Функция SetCookie возвратит FALSE:
if (SetCookie("Test","Value")) echo "<h3>Cookie успешно установлен!</h3>";
else echo "<h3>Cookie установить не удалось!</h3>";
// Выводит 'Cookie установить не удалось!'.
?>

Cookie установить не удалось, поскольку перед посылкой заголовка Cookie мы вывели в браузер строку "Hello".

Чтение значений Cookies

Получить доступ к Cookies и их значениям достаточно просто. Они хранятся в суперглобальных массивах и $_COOKIE и $HTTP_COOKIE_VARS.

Доступ к значениям осуществляется по имени установленных Cookies, например:

echo $_COOKIE['my_cookie'];
// Выводит значения установленной Cookie 'My_Cookie'

Пример установки Cookie и последующего его чтения:

<?php
// Устанавливаем Cookie 'test' со значением 'Hello' на один час:
SetCookie("test","Hello",time()+3600);
// При следующем запросе скрипта выводит 'Hello':
echo @$_COOKIE['test'];
?>

В рассмотренном примере при первом обращении к скрипту устанавливается Cookie "test" со значением "hello". При повторном обращении к скрипту будет выведено значение Cookie "test", то есть строка "Hello".

СЕССИИ

Сессия - это сеанс, во время которого система идентифицирует зашедшего на сайт пользователя. Для этого надо выдать ему уникальный идентификатор и попросить передавать его с каждым запросом. Идентификатор - это обычная переменная. По умолчанию ее имя - PHPSESSID.

Задача PHP отправить ее браузеру, чтобы тот вернул ее со следующим запросом. Переменную можно передать только двумя способами: в cookies или POST/GET запросом.

PHP использует оба варианта.

За это отвечают две настройки в php.ini:

session.use_cookies - если равно 1, то PHP передает идентификатор в cookies, если 0 - то нет.
session.use_trans_sid если равно 1, то PHP передает его, добавляя к URL и формам, если 0 - то нет.

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

<a href="/index.php">Index</a>
превращается в

<a href="/index.php?PHPSESSID=9ebca8bd62c830d3e79272b4f585ff8f">Index</a>
а к формам добавляется скрытое поле

<input type="hidden" name="PHPSESSID" value="00196c1c1a02e4c37ac04f921f4a5eec" />

И браузер при клике на любую ссылку, или при нажатии на кнопку в форме, пошлет в запросе нужную нам переменную - идентификатор сессии!

Затем, на сервере создается файл, имя которого совпадает с этим идентификатором. В этот файл могут писаться какие-то данные из ассоциативного массива $_SESSION.

Для того, чтобы иметь доступ к переменным сессии на любых страницах сайта, надо написать только одну строчку в самом начале КАЖДОГО файла, в котором нам нужны сессии:
session_start();

И далее обращаться к элементам массива $_SESSION:
$_SESSION['test']='Hello world!';

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

session_start();
if ($_SESSION['authorized']<>1) {
header("Location: /auth.php");
exit;
}

Удаление переменных из сессии

Если в настройках PHP включена переменная register_globals=off, то достаточно написать

unset($_SESSION['var']);

Если же нет, то тогда рядом с ней надо написать:

session_unregister('var');

Сравнение механизмов идентификации пользователей при помощи Cookies и Session

Cookies — это просто пара имя-значение, которые сервер может оставить у клиента (браузера). Наглядно:

1. Приходит клиент, спрашивает у сервера страницу.
2. Сервер по IP определяет геолокацию клиента и в заголовках ответа может установить cookies. Например, выдав заголовок: Set-Cookie: country=russia. При следующем обращении серверу уже не надо проверять IP, он может взять готовое значение из cookies, если они разрешены у клиента.

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

Как правило, сессии реализуются используя cookies и идентификаторы сессий. Т.е. сервер со своей стороны создает уникальный идентификатор, например, «1a2b3c» (session_id), а клиента просит его запомнить. Обычно — при помощи cookies, говоря что-то в духе Set-Cookie: PHPSESSID=1a2b3c (где «PHPSESSID» — имя сессии). Со своей стороны сервер где-то в файле хранит различные данные, которые ему приказано связывать с этой сессией.

Если куки у пользователя отключены, то перед отдачей страницы пользователю сервер переписывает все ссылки в ней, добавляя к ним параметр «?PHPSESSID=1a2b3c». Таким образом сервер получает идентификатор сессии.

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