В этот раз я расскажу, как сделать свой обработчик, как его активировать, и какие подводные камни я нашел.
Работа с данными сессии разделена на 6 разных этапов. Соответственно, и обработчик сессии должен перехватить все 6 функций. Вот их условные названия: open, read, write, delete, gc (garbage collection) и close. Я специально не поставил круглые скобки после имен функций, чтоб они в тексте не путались со встроенными функциями PHP.
Рассмотрим их работу подробнее:
open.
Назначение этой функции - подготовка ко всем остальным операциям. Функция вызывается автоматически сразу после старта сессии. В параметрах ей передаются путь к директории, где предполагается хранить файлы с данными сессий, и имя сессии.
Путь берется из php.ini ("session.save_path") либо устанавливается в программе функцией session_save_path().
Имя сессии может использоваться для составления имени файла с данными, а можно его просто игнорировать - вероятность повтора строки MD5 крайне мала.
В литературе встречается мнение, что если данные сессии хранятся в базе данных, то в этой функции можно произвести подключение к БД. Я считаю, если БД есть и используется, то не только для хранения данных сессии, и подключение можно произвести раньше, в основной программе. Так проще и понятней.
read.
Назначение - считать данные сессии. Функция вызывается сразу после open. Единственный параметр - идентификатор сессии. Вернуть функция должна строку, соответствующую формату входного параметра функции unserialize(). Если данных нет, то она должна вернуть пустую строку.
В этой функции также важно понять, есть ли источник данных, т.к. сессия могла быть ранее уничтожена сборщиком мусора (gc) или функцией delete. Также здесь можно проверять и устанавливать блокировки (об этом расскажу в последующих частях).
write.
Назначение - запись данных сессии. Функция автоматически вызывается при следующих обстоятельствах: завершение сессии по желанию программиста и по завершению программы (когда вывод в браузер окончен и сообщения об ошибках отобразить в браузере уже нельзя). Входных параметров два: идентификатор сессии и сохраняемые данные в сериализованном виде. Возвращаемое значение должно символизировать результат работы, но и отрицательный результат уже ни на что не повлияет, если вывод завершен (данные не сохранены, работа
окончена, моем руки).
Не стоит надеяться, что раз источник данных был доступен функции read, то в write не надо проверять его доступность. Файл (или запись в БД) вполне могли уже удалить. По крайней мере, есть такая вероятность, и проверки будут не лишними. Правда, если в read отрыть файл, сохранить его дескриптор и не закрывать, то в write файл будет гарантированно существовать (в *nix системах он может быть еще удален, но физически писать в него еще можно), если конечно не додуматься до хранения временных файлов на сетевом
диске или съемном носителе.
Принудительная запись осуществляется функцией session_write_close(). Начиная с PHP 4.3.11, у нее есть более благозвучное имя - session_commit().
delete.
Назначение - удалить данные сессии. Вызывается автоматически некоторыми встроенными функциями. Например, session_destroy() (с версии 4.3.3), или session_regenerate_id() (с версии 5.1.0). Входной параметр один - идентификатор сессии. Так стоит проверить, существует ли объект для удаления, или, по крайней мере, подавить вывод ошибок - в их обработке смысла нет.