Языки программирования

Cookie и отслеживание сеанса

Начнем с cookie

Cookie-файл — это небольшой фрагмент информации, который хранится на клиентском компьютере (либо в памяти приложения браузера, либо в виде небольшого файла, записанного на жесткий диск компьютера пользователя). Cookie-файл содержит данные в виде пар «имя-значение».
Под термином «установка cookie-файла» подразумевается связывание имени со значением и сохранение данных, представляющих пару «имя-значение» на клиентском компьютере. Под термином «получение, или чтение cookie-файла» подразумевается использование имени для выборки значения.
Вследствие того, что cookie обычно связываются с конкретным пользователем, в них часто сохраняется уникальный идентификатор пользователя (UIN). Этот идентификатор заносится в базу данных на сервере и используется в качестве ключа для выборки из базы всей информации, связанной с этим идентификатором.

Компоненты cookie

В cookie хранятся компоненты, при помощи которых разработчик может ограничивать использование cookie с позиций домена, пути, срока действия и безопасности. Ниже приведены описания различных компонентов cookie:
  • Имя — имя cookie является обязательным параметром, по которому программа ссылается на cookie. Можно провести аналогию между именем cookie и именем переменной.
  • Значение — фрагмент данных, связанный с именем cookie. В этих данных может храниться любая информация — идентификатор пользователя, цвет фона, текущая дата.
  • Срок действия — дата, определяющая продолжительность существования cookie. Как только текущая дата и время превосходят заданный срок действия, cookie становится недействительным и перестает использоваться. В соответствии со спецификацией cookie устанавливать срок действия для cookie необязательно.
  • Домен — домен, который создал cookie и может читать его значение. Если домен состоит из нескольких серверов и доступ к cookie должен быть разрешен всем серверам, то имя домена можно задать в форме .phprecipes.com. В этом случае все потенциальные домены третьего уровня, принадлежащие сайту PHPrecipes (например, wap.phprecipes.com или news.phprecipes.com), смогут работать с cookie. По соображениям безопасности cookie могут устанавливаться только для домена сервера, пытающегося создать cookie.
  • Путь — URL, с которого предоставляется доступ к cookie. Любые попытки получения доступа к cookie за пределами этого пути пресекаются. Данный компонент необязателен; если он не задан, по умолчанию используется путь к документу, создавшему cookie.
  • Безопасность — параметр, показывающий, допускается ли чтение cookie в небезопасной среде. По умолчанию используется значение FALSE.

Cookie и РНР

Чтобы задать значение cookie в РНР нужно просто использовать стандартную функция setcookie( ). Функция сохраняет cookie на компьютере пользователя. Синтаксис функции setcookie( ):
int setcookie (string имя [string значение [, int дата [, string путь [, string домен [, int безопасность]]]]])
Ниже приведены параметры функции. Все эти параметры, кроме первого, являются необязательными:
  • name — имя cookie-файла (аналогичное имени переменной).
  • value — значение, которое должно быть сохранено в cookie-файле (аналогично значению, которое должно было быть присвоено переменной). Если этот параметр не задан, то cookie-файл, указанный в качестве первого параметра, удаляется.
  • expire — значение, определяющее, когда должен истечь срок существования данного cookie-файла. Значение 0 (применяемое по умолчанию) указывает, что cookie-файл должен существовать до закрытия программы браузера. Любое другое целое число интерпретируется как абсолютное значение времени в секундах, когда cookie-файл должен стать недействительным.
  • path — в случае, предусматриваемом по умолчанию, рассматриваемый cookie-файл может считываться (и устанавливаться) на любой странице, при формировании которой сценарий обращается к указанному подкаталогу корневого каталога документов веб. Возможность задать путь к подкаталогу (например, «/forum/») позволяет подчеркнуть различия между cookie-файлами, имеющими одинаковое имя, но устанавливаемыми на других сайтах или в других подобластях веб-сервера (в данном примере предполагается, что cookie-файл будет действительным только в области forum). В обозначении пути должна обязательно присутствовать заключительная косая черта.
  • httponly — Cookie-файлы, заданные с этим флагом, передаются только с помощью запросов протокола HTTP. Значением по умолчанию является FALSE.
  • domain — в случае, предусматриваемом по умолчанию, проверка домена, доступа к которому требует клиент, не производится. Если же данный параметр не пуст, то имя домена должно совпадать с ним.
  • secure — значением по умолчанию является 0 (false). Если этот параметр равен 1, или true, то cookie-файл будет передаваться только через соединение с защищенным сокетом (иначе говоря, по протоколу SSL или HTTPS).

Удаление cookie-файлов

Чтобы удалить cookie-файлы нужно вызвать функцию setcookie() точно с такими же параметрами, как и при установке cookie-файла, за исключением самого значения, которое должно быть задано в виде пустой строки.
Такой вызов не приводит к тому, что устанавливается cookie-файл со значением, равным пустой строке, а фактически влечет за собой удаление cookie-файла. Следует учитывать, что, если при установке cookie-файла использовались параметры с указанием пути или домена, эти параметры необходимо также применять для отмены установки cookie-файла.

Уникальные идентификаторы

В РНР предусмотрено простое средство для создания уникальных UIN — встроенная функция uniqid(). Это функция генерирует уникальный идентификатор из 13 символов, значение которого основано на текущем времени. Синтаксис функции uniqid( ):
int uniqid(string префикс [б boolean дополнение])
В параметре префикс передается строка, с которой должен начинаться UIN. Поскольку этот параметр является обязательным, при вызове необходимо передать хотя бы пустую строку.

Если необязательный параметр дополнение равен TRUE, функция uniqid( ) генерирует UIN из 23 символов. Чтобы быстро создать уникальный идентификатор, достаточно при вызове uniqid( ) передать один параметр — пустую строку:
$uniq_id = uniqid(" ");

// Генерируется строка из 13 символов - например. '39b3209ce8ef2'

В другом варианте сгенерированное значение присоединяется к строке, определяемой параметром префикс:

$uniq_id = uniqid("php", FALSE):

// Генерируется строка из 16 символов - например. 'php39b3209ce8ef2'

Отслеживание сеанса

Сеансом (session) называется период времени, который начинается с момента прихода пользователя на сайт и завершается, когда пользователь покидает сайт.
В течение сеанса часто возникает необходимость в сохранении различных переменных, которые бы «сопровождали» пользователя при перемещениях на сайте, чтобы вам не приходилось вручную кодировать многочисленные скрытые поля или переменные, присоединяемые к URL.
Чтобы начать сеанс, нужно добавить в начало PHP-сценария вызов функции session_start() – лишь после этого появится возможность сохранять и получать данные, принадлежащие сеансу.
Функцию session_start() следует вызвать до вызова функции header() и вообще до того, как браузеру клиента будет отправлена хоть какая-нибудь информация, в противном случае сеанс может работать некорректно.
Обращение к переменным сеанса заключается в использовании суперглобальной переменной $_SESSION с подстановкой имени требуемой переменной в квадратных скобках.
В примере ниже показан простой счетчик просмотра страницы за один сеанс (для простоты этот пример основан на обновлении одной и той же страницы несколько раз, однако, ни что не ограничивает в применении сеансов на нескольких страницах, но не забывайте добавлять на каждую из них вызов метода session_start()):
if (!isset($_SESSION['count_view']))
{
	echo '<h1>Вы в первый раз посещаете данную страницу.</h1>';
	$_SESSION['count_view'] = 1;
}
else
{
	++$_SESSION['count_view'];
	echo '<h1>Количество посещений вами этой страницы за 1 сеанс: '
	    .$_SESSION['count_view'].'</h1>';
}

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

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

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

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

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

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

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

Сборка мусора

Сборка мусора (garbage collection) – это то, что должно произойти с содержимым сеанса на стороне сервера после завершения сеанса или по достижению предельного времени отсутствия активности.
Если сервер не будет периодически удалять информацию о старых сеансах, она будет накапливаться до бесконечности, занимая дисковое пространство и мешая работе сервера. Сборка мусора производится автоматически, при выполнении этой операции удаляются все данные устаревших сеансов.
В PHP можно регулировать нагрузку на механизм сборки мусора, чтобы не удалять старые файлы сеансов при каждом обращении к сеансу.
По умолчанию предельное время жизни файлов сеанса составляет 1440 с, или 24 мин. Для очень надежных сайтов это время не слишком велико, однако в PHP есть ряд параметров, управляющих удалением мусора.
Файл сеанса может быть удален по истечении заданного интервала времени, но он может продолжать свое существование на диске сервера и дольше – все зависит от количества созданных сеансов. В файле инициализации PHP (php.ini) отношение к сборке мусора имеют следующие параметры:
  • session.gc_maxlifetime (значение по умолчанию 1440);
  • session.gc_probability (значение по умолчанию 1);
  • session.gc_divisor (значение по умолчанию 100).
В этих переменных символы gc означают garbage collector (сборщик мусора). Если на сервере достаточно дискового пространства, можно увеличить предельное время ожидания, чтобы предотвратить завершение большинства или даже всех сеансов до закрытия браузера.
Однако во многих случаях требуется ограничить предельную продолжительность сеанса – этого можно добиться, изменив срок хранения cookie.
Чтобы определить, пора ли запускать сборщик мусора, интерпретатор PHP генерирует случайное число в диапазоне от 0 до 1. Если полученное число меньше, чем дробная часть отношения session.gc_probability / session.gc_divisor, запускается сборщик мусора.
Самоучитель по PHP