Класс Session предоставляет возможность управлять механизмом буферизации страниц. Переменная этого класса $allow_cache принимает значения no, private и public. Правила умолчания в данном случае зависят от конкретной версии библиотеки PHPLib. Скажем, в версии 7.2 значение этой переменной по умолчанию равно private, а в последующих версиях - no. Методика кэширования страниц, предлагаемая библиотекой PHPLib, очень похожа на механизм буферизации, предоставляемый функциями сеанса в PHP 4.0
Сериализация
В системе PHP 3.0 сериализовать объекты сложно. Функция serialize() неправильно сохраняет методы класса, а вручную это сделать невозможно. В механизме поддержки объектов в программе PHP 3.0 отсутствовало одно важное средство - интроспекция. Нельзя было получить имя класса и имя его родительского класса. Поэтому при разработке библиотеки PHPLib надо было использовать обходные маневры. В классах библиотеки были предусмотрены два дополнительных поля - $classname и $persistent_slots, - которые соответственно содержали имя класса и переменных класса, подлежащих сериализации. Зная имя класса, библиотека PHPLib имела возможность генерировать код PHP, создающий экземпляр этого класса ($class = new class), и сохранить этот код в банке данных сеанса. При повторном обращении к данным сеанса указанная инструкция выполнялась с помощью функции eval(). Помните пример с самомодифицирующимся счетчиком из главы 2? В библиотека PHPLib используется тот же самый принцип.
При работе с пакетом PHP 4.0 подобные обходные маневры не нужны. В нем предусмотрены функции get_class() и get_parent_class(), которые обеспечивают адекватный механизм интроспекции. А функция serialize() работает с объектами значительно лучше.
Работа с сеансами
Применение объекта сеанса библиотеки PHPLib, как правило, нисколько не сложнее, чем использование библиотеки управления сеансами пакета PHP 4.0. Это демонстрирует образец сценария, приведенный в листинге 6.3. В нем выполняются те же действия, что и в примере, который мы рассматривали в главе 4.
Листинг 6.3. Простейший пример использования класса Session библиотеки PHPLib
-
//явным образом создать экземпляр объекта
-
$sess = new Example_Session;
-
//начать сеанс
-
$sess->start();
-
//зарегистрировать переменную сеанса
-
$sess->register("counter");
-
//инициализировать счетчик
-
if(!isset($counter))
-
{
-
$counter = 0;
-
}
-
//вывести идентификатор сеанса и значение счетчик
-
printf("Идентификатор сенса: %s
", $sess->id);
-
print("Значение счетчика: $counter");
-
//увеличить значение счетчика
-
$counter++;
-
//сохранить информацию о состоянии сеанса
-
$sess->freeze();
Единственным существенным различием между этим примером и примером из главы 4 является то, что в библиотеке PHPLib используется объектно-ориентированный подход.
Так же как и библиотека управления сеансами PHP 4.0, библиотека PHPLib применяет для хранения данных сеанса модули хранения (которые в библиотеке PHPLib называются контейнерами). Имена классов контейнеров начинаются с префикса CT_. Самым распространенным способом хранения данных сеанса являются базы данных в формате SQL, но в библиотеке PHPLib предусмотрена возможность работы и с другими классами контейнеров.
Библиотека PHPLib 7.2 содержит следующие классы контейнеров.
-
Класс CT_Sql является контейнером, используемым по умолчанию, и сохраняет данные сеанса в базе данных. В этом классе имеются следующие элементы данных.
Имя | Описание |
---|---|
$database_class | Имя класса DB_Sql, которое следует использовать для связи с базой данных |
$database_table | Имя таблицы для хранения данных сеанса |
$encoding_mode | Эта переменная определяет способ хранения данных сеанса. Она может принимать два значения: base64 и slashes. Без особой необходимости не следует изменять значение, установленное по умолчанию (base64), - предусматривающее необходимость представления данных сеанса перед их записью в базу данных в кодировке Base64. При отладке можно использовать альтернативный метод (константа slashes), который позволяет хранить данные в таблице как обычный текст |
-
С точки зрения реализованных в классе возможностей, контейнеры CT_ Split_Sql идентичны контейнерам CT_Sql. Данный класс следует использовать, если база данных не может сохранить все данные сеанса в одном поле, особенно в тех случаях, когда в базе возникают проблемы с обработкой больших двоичных объектов (BLOBs). Класс CT_Split_Sql несовместим с таблицами CT_Sql.
Чтобы изменить размер частей, на которые класс разбивает данные сеанса, можно использовать переменную $split_length, по умолчанию ее значение равно 4096 (4 Кбайт).
-
Контейнер CT_Shm записывает данные сеанса в совместно используемую память. Чтобы с этим классом можно было работать, требуется, чтобы пакет РHP был скомпилирован с включением режима поддержки совместно используемой памяти. Контейнеры CT_Shm работают быстрее, чем другие виды контейнеров, так как позволяют осуществлять прямой доступ к хранимым данным. Однако у таких контейнеров есть один существенный недостаток: если вам по какой-либо причине потребуется перезагрузить сервер, все данные сеанса будут потеряны. Кроме того, из-за большого расхода памяти ограничено число параллельных сеансов. Каждый сеанс получает определенное количество памяти (оно зависит от количества и размера переменных сеанса), и когда ресурсы памяти будут исчерпаны, новый сеанс создать не удастся.
Переменные этого класса отличаются от переменных класса CT_Sql.
Параметр | Описание |
---|---|
$max_sesions | Максимальное количество одновременных активных сеансов. По умолчанию - 500 |
$shm_key | Уникальный ключ сегмента совместно используемой памяти. Важно, чтобы он был уникальным для каждого приложения |
$shm_size | Размер сегмента совместно используемой памяти (в байтах). Приблизительно его можно рассчитать по формуле shn_size = = max_sessions * session_size, где размер сеанса в среднем имеет значение примерно 600 байт. Значение по умолчанию равно 64 000 (64 Кб) |
-
Контейнер CT_Dbm использует для хранения данных сеанса файл в формате DBM операционной системы UNIX. В базах данных такого типа информация сохраняется в виде пар "ключ - значение" средствами обычной файловой системы. Единственной переменной, которой надо присвоить соответствующее значение (имя вашего файла DBV), является $dbm_file. Указанный файл обязан существовать; к нему должен быть установлен соответствующий режим доступа; серверу требуется доступ для записи к этому файлу.
-
Контейнер CT_Ldap позволяет хранить данные на сервере LDAP (Light Directory Access Protocol, облегченный протокол доступа к каталогам). Чтобы получить возможность использовать контейнеры подобного типа, скомпилируйте пакет PHP с включенной поддержкой протокола LDAP. Класс CT_Ldap располагает следующими свойствами.
Свойство | Описание |
---|---|
$ldap_host, $ldap_port | Имя хоста и номер порта сервера LDAP |
$rootdn, $rootpw | Имя и пароль, используемые для связи с сервером LDAP |
$basedn | Под этим именем будут храниться данные сеанса |
$objclass | Имя объектного класса (его можно сопоставлять с именем соответствующей таблицы SQL) |
Если вы заглянете в файл local.inc, то увидите ряд определений классов. Три из них имеют непосредственное отношение к нашему примеру.
-
class DB_Example extends DB_Sql {
-
var $Host = "localhost";
-
var $Database= "phplib";
-
var $User = "tobias";
-
var $Password = "justdoit";
-
}
-
class Example_CT_Sql extends CT_Sql{
-
var $database_class = "DB_Example"; ##к какой базе данных
-
##подключаться
-
var $database_table = "active_sessions"; ##здесь следует
-
##искать наши данные
-
}
-
class Example_Session extends Sesion{
-
var $classname = "Example_Session";
-
var cookiename = ""; ##по умолчанию будет использоваться имя
-
##класса
-
var $magic = "Hocuspocus"; ##исходное значение
-
##идентификатора
-
var $mode = "cookie"; ##повторная генерация идентификатора
-
## сеанса производится через файл
-
##персональных настроек
-
var $fallback_mode = "get";
-
var $lifetime = 0; ##0-работа с персональными
-
##настройками, иначе - время (в минутах),
-
##по истечении которого информация о сеансе
-
##считается устаревшей
-
var $that_class = "Example_CT_Sql"; ##имя контейнера
-
##для хранения данных
-
var $gc_probability = 5;
-
}
Как нетрудно видеть, между классами возникают определенные отношения: в классе Example_Session переменная $that_class получает имя класса Example_CT_Sql, а переменная $database класса Example_CT_Sql указывает на класс DB_Sql. Рис. 6.1 иллюстрирует эти отношения.