7.10. Сеансы
Для написания Web-приложения, вероятно, потребуется информация, которая бы могла ассоциироваться с каждым пользователем. При этом может потребоваться при переходе от одной страницы к другой запомнить имя пользователя. Информацию можно собирать последовательно от формы к форме. Можно попытаться передавать увеличивающийся объем информации в скрытых полях форм, но такой прием считается непрактичным. Лучшим решением в данном случае будет использование сеанса, когда каждому посетителю присваивается определенный уникальный идентификатор, с помощью которого можно обращаться к сохраненной информации в файле или базе данных.
Раньше разработчикам PHP требовалось создавать свой собственный код для поддержки сеансов, но в PHP 4 усилиями Саши Шуманна (Sascha Schumann) и Андрея Змиевского (Andrei Zmievski) были добавлены новые функции поддержки сеансов. Эта оригинальная система заключается в регистрации глобальных переменных с использованием дескриптора сеанса. Для этих целей предпочтительно использовать массив _SESSION. PHP сохраняет содержимое этого массива в специальных файлах на сервере. Если пользователь запрашивает другую страницу, PHP восстанавливает в массиве эти данные.
Идентификатор сеанса представляет собой длинную последовательность чисел и букв, отсылаемых пользователю в виде файла cookie. Весьма вероятно, что браузер пользователя отвергнет файлы cookie, и в этом случае PHP создаст константу, позволяющую отправлять идентификатор сеанса в URL. Это константа SID, которая содержит полное объявление метода GET и с помощью которой можно завершить URL.
Рассмотрим листинг 7.6, представляющий собой простейший сценарий, отслеживающий имя пользователя и количество посещений страницы. Для активизации сеансов необходимо вызвать функцию session_start. Это позволяет отправлять файл cookie в браузер, и поэтому он должен вызываться до отправки любого содержимого. В предыдущих версиях PHP для сохранения каждой глобальной переменной требовался вызов функции session_register. Начиная с PHP 4.1 улучшенный интерфейс для данных сеанса обеспечивает массив _SESSION.
В листинге 7.6 используются две сеансовые переменные - Name и Count. Первая из них предназначена для отслеживания имени пользователя, а вторая - для подсчета числа обращений пользователя к странице. Будучи однажды помещенными в массив _SESSION, эти значения остаются в сеансе до его завершения или до явного сброса этого значения. Перед запуском HTML-документа сценарий, представленный в данном примере, устанавливает значение переменной Name равным значению, введенному в форме, после чего он инкрементирует счетчик страницы.

| Листинг 7.6. Использование сеансов_
<?php
// начало сеанса session_start();
// установить переменную равной вводимому значению в форме if(isset($_REQUEST['inputName']))
{
$_SESSION['Name'] = $_REQUEST['inputName']; 
// инкрементировать счетчик при каждой загрузке страницы if(isset($_SESSION['Count']))
$_SESSION['Count']++;
else
//начать с 1 $_SESSION['Count'] = 1;
?>
<html> <head>
<title>Листинг 7.6</title>
</head>
<body>
<?php
// вывод диагностической информации
print("<b> Диагностическая информация</b><br>n"),• print("Имя сеанса: " . session_name() . "<br>n"); print("Идентификатор сеанса: " . session_id() . "<br>n"); print("Имя модуля сеанса: " . session_module_name() .
"<br>n");
print("Путь сохранения сеанса: " . session_save_path() .
"<br>n");
print("Закодированный сеанс:" . session_encode() . "<br>n");
print("<hr>n");
if(isset($_SESSION['Name']))
{
print("Привет, {$_SESSION['Name']}!<br>n");
}
print("E>bi просматривали эту страницу " .
$_SESSION['Count'] . " раз!^^^"); // отобразить форму ввода имени print("<form " .
"action="{$_SERVER['PHP_SELF']}" " .
"method="post">" .
"<input type="text" name="inputName" " . "value=""><br>n" .
"<input type="готово" value="change name"><br>n" . "</form>");
// для перезагрузки этой страницы использовать ссылку print("<a href="{$_SERVER['PHP_SELF']}">reload</a><br>n");
?>
</body> </html>

 Первая часть содержимого, которое выдает эта страница, содержит информацию о сеансе. Вместе с другими параметрами сеанса в файле php.ini устанавливается имя сеанса, которое используется для присвоения имени файлу cookie, хранящего идентификатор сеанса. Сам по себе идентификатор является длинной строкой, содержащей буквы и цифры, сгенерированные случайным образом. По умолчанию PHP сохраняет сеансы в каталоге /tmp, используя встроенный дескриптор files. Этот каталог в ОС Windows не является стандартным, и при его отсутствии сеансы будут работать с ошибками.
С помощью функции session_set_save_handler можно создать собственный дескриптор. В главе 8, "Браузер ввода-вывода", приводится пример дескриптора сохранения сеанса. PHP кодирует данные сеанса с помощью трансформации - метода сжатия переменных в подходящие для хранения текстовые строки. Изучив файлы, сохраненные в каталоге /tmp, вы легко обнаружите, что они соответствуют строкам, возвращаемым функцией session_encode.
Как подчеркивалось выше, PHP отправляет идентификаторы сеанса с файлами cookies, но браузер может блокировать их прием. PHP может определить, что браузер не принимает файлы cookies, и в этой ситуации он модифицирует все формы и ссылки с тем, чтобы они включали идентификатор сеанса. Он только модифицирует относительные URL, что помогает избежать отправки идентификаторов на другой узел. Для восстановления можно использовать константу SID, содержащую строку, в которой указаны имя сеанса, знак равенства и идентификатор сеанса. Эту строку можно добавить в URL. Если браузер возвращает файл cookie данного сеанса в сценарий, константа SID будет пустой.