session_set_save_handler

(PHP 4, PHP 5, PHP 7)

session_set_save_handlerУстанавливает пользовательские обработчики хранения сессии

Описание

session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc , callable $create_sid = ? , callable $validate_sid = ? , callable $update_timestamp = ? ) : bool

Начиная с PHP 5.4 появилась возможность регистрировать следующий прототип:

session_set_save_handler ( object $sessionhandler , bool $register_shutdown = true ) : bool

session_set_save_handler() устанавливает пользовательские обработчики хранения сессии, которые используются для сохранения и получения данных, связанных с сессией. Это особенно полезно, когда предпочтительным является метод хранения, отличный от тех, которые предоставляются сессиями PHP, например, хранение данных сессии в локальной базе данных.

Список параметров

Данная функция имеет два определения (прототипа).

sessionhandler

Экземпляр класса, реализующий интерфейс SessionHandlerInterface и необязательные SessionIdInterface и/или SessionUpdateTimestampHandlerInterface, такой как SessionHandler, для регистрации в качестве обработчика сессии. Только начиная с PHP 5.4.

register_shutdown

Зарегистрировать session_write_close() как функцию register_shutdown_function().

или
open

Callback-функция со следующей сигнатурой:

open ( string $savePath , string $sessionName ) : bool

Callback-функция open работает как конструктор в классах и выполняется при открытии сессии. Это первая сallback-функция, которая выполняется, когда сессия стартует автоматически либо вручную через session_start(). Возвращаемое значение true в случае успеха, false в случае неудачи.

close

Callback-функция со следующей сигнатурой:

close ( ) : bool

Callback-функция close работает как деструктор в классах и выполняется после того, как была вызвана callback-функция write. Она также вызывается при вызове session_write_close(). Возвращаемое значение должно быть true в случае успеха, false в случае неудачи.

read

Callback-функция со следующей сигнатурой:

read ( string $sessionId ) : string

Callback-функция read должна всегда возвращать кодированную (сериализованную) строку сессии или пустую строку, если нет данных для чтения.

Эта callback-функция вызывается внутренним механизмом PHP при старте сессии или при вызове session_start(). Перед тем, как будет вызвана эта callback-функция, PHP вызовет callback-функцию open.

Возвращаемое значение данной callback-функции должно быть в точно таком же сериализованном формате, который изначально передавался для хранения в callback-функцию write. Возвращаемое значение будет автоматически десериализовано PHP и использовано для заполнения суперглобальной переменной $_SESSION. Даже если данные похожи на результат serialize(), стоит помнить, что это другой формат сериализации, который определён ini-дерективой session.serialize_handler.

write

Callback-функция со следующей сигнатурой:

write ( string $sessionId , string $data ) : bool

Callback-функция write вызывается, когда сессия должна быть сохранена и закрыта. Данная callback-функция принимает идентификатор текущей сессии и сериализованную версию суперглобальной переменной $_SESSION. Используемый внутри PHP метод сериализации определён ini-дерективой session.serialize_handler.

Переданные в эту callback-функцию сериализованные данные сессии должны быть сохранены в связи с переданным идентификатором сессии. При получении этих данных, callback-функция read должна вернуть то же самое значение, что было передано в callback-функцию write.

Данная callback-функция вызывается, когда PHP завершает работу или явно при вызове session_write_close(). Следует помнить, что после выполнения этой callback-функции, PHP выполнит callback-функцию close.

Замечание:

Обработчик "write" не выполнится до тех пор, пока выходной поток не будет закрыт. Таким образом, вывод отладочных операторов в обработчике "write" никогда не отобразится в браузере. Если необходим вывод отладочной информации, рекомендуется записывать отладочные данные в файл.

destroy

Callback-функция со следующей сигнатурой:

destroy ( string $sessionId ) : bool

Данная callback-функция вызывается, когда сессия уничтожается с помощью session_destroy() или при вызове session_regenerate_id() с параметром destroy, установленным в true. Возвращаемое значение должно быть true в случае успеха, false в случае неудачи.

gc

Callback-функция со следующей сигнатурой:

gc ( int $lifetime ) : bool

Callback-функция сборщика мусора периодически вызывается PHP для очистки данных старых сессий. Частота контролируется директивами session.gc_probability и session.gc_divisor. Значение lifetime, которое передаётся в данную callback-функцию может быть установлено в session.gc_maxlifetime. Возвращаемое значение должно быть true в случае успеха, false в случае неудачи.

create_sid

Callback-функция со следующей сигнатурой:

create_sid ( ) : string

Данная callback-функция выполняется, когда требуется новый идентификатор сессии. Не предусматривает параметров, а возвращаемое значение должно быть строкой, которая является допустимым идентификатором сессии для вашего обработчика.

validate_sid

Callback-функция со следующей сигнатурой:

validate_sid ( string $key ) : bool

Callback-функция выполняется, когда должна быть запущена сессия, предоставляется идентификатор сессии и включается session.use_strict_mode. key - это идентификатор сессии для проверки. Идентификатор сессии действителен, если сессия с таким идентификатором уже существует. Возвращаемое значение должно быть true в случае успешного выполнения или false в случае возникновения ошибки.

update_timestamp

Callback-функция со следующей сигнатурой:

update_timestamp ( string $key , string $val ) : bool

Callback-функция выполняется при сессии. key - это идентификатор сессии, val - это данные сессии. Возвращаемое значение должно быть true в случае успешного выполнения или false в случае возникновения ошибки.

Возвращаемые значения

Возвращает true в случае успешного завершения или false в случае возникновения ошибки.

Примеры

Пример #1 Пользовательский обработчик сессии: полный код смотрите в описании SessionHandlerInterface.

Следующий код для PHP версии 5.4.0 и выше. Здесь только продемонстрирован вызов session_set_save_handler, полный пример можно посмотреть в описании SessionHandlerInterface.

Заметьте, что с session_set_save_handler() мы используем ООП-прототип и регистрируем функцию завершения, используя флаг параметра функции. Это обычно рекомендуется при регистрации объектов в качестве обработчиков хранения сессии.

<?php
class MySessionHandler implements SessionHandlerInterface
{
    
// здесь реализация интерфейса
}

$handler = new MySessionHandler();
session_set_save_handler($handlertrue);
session_start();

// устанавливаем и получаем значения по ключу из $_SESSION

Пример #2 Пользовательский обработчик сессии с использованием объектов

Следующий код для PHP версий ниже 5.4.0.

Следующий пример показывает реализацию файлового хранилища сессий, похожего на стандартный обработчик PHP хранения сессии files. Этот пример может быть легко расширен для реализации хранилища в базах данных, используя ваш любимый движок базы данных, который поддерживает PHP.

Заметьте, что мы дополнительно регистрируем функцию завершения session_write_close(), используя register_shutdown_function() в PHP версии меньше 5.4.0. Это обычно рекомендуется при регистрации объектов в качестве обработчиков хранения сессии для PHP версий меньше 5.4.0.

<?php
class FileSessionHandler
{
    private 
$savePath;

    function 
open($savePath$sessionName)
    {
        
$this->savePath $savePath;
        if (!
is_dir($this->savePath)) {
            
mkdir($this->savePath0777);
        }

        return 
true;
    }

    function 
close()
    {
        return 
true;
    }

    function 
read($id)
    {
        return (string)@
file_get_contents("$this->savePath/sess_$id");
    }

    function 
write($id$data)
    {
        return 
file_put_contents("$this->savePath/sess_$id"$data) === false false true;
    }

    function 
destroy($id)
    {
        
$file "$this->savePath/sess_$id";
        if (
file_exists($file)) {
            
unlink($file);
        }

        return 
true;
    }

    function 
gc($maxlifetime)
    {
        foreach (
glob("$this->savePath/sess_*") as $file) {
            if (
filemtime($file) + $maxlifetime time() && file_exists($file)) {
                
unlink($file);
            }
        }

        return 
true;
    }
}

$handler = new FileSessionHandler();
session_set_save_handler(
    array(
$handler'open'),
    array(
$handler'close'),
    array(
$handler'read'),
    array(
$handler'write'),
    array(
$handler'destroy'),
    array(
$handler'gc')
    );

// предотвращает непредвиденные эффекты при использовании объектов в качестве обработчиков хранения сесси
register_shutdown_function('session_write_close');

session_start();
// устанавливаем и получаем значения по ключу из $_SESSION

Примечания

Внимание

При использовании объектов в качестве обработчиков хранения сессии, важно регистрировать функцию завершения с помощью PHP, чтобы избежать непредвиденных побочных эффектов от того, как внутренний механизм PHP уничтожает объекты при завершении, что может предотвратить вызовы write и close. Как правило, вы должны регистрировать 'session_write_close', используя функцию register_shutdown_function().

Начиная с PHP 5.4.0 вы можете использовать session_register_shutdown() или просто установить флаг 'register_shutdown' при вызове session_set_save_handler(), используя метод ООП и передать экземпляр класса, реализующего интерфейс SessionHandlerInterface.

Внимание

Начиная с версии PHP 5.0.5 обработчики write и close вызываются после деструктора объекта и поэтому не могут использовать его контекст или бросать исключения. Исключения не могут быть обработаны, так как не будут пойманы, не будет оторажена трассировка стека исключения и выполнение просто прекратится неожиданно. Однако при этом, деструкторы объекта могут использовать сессии.

Можно вызвать session_write_close() из деструктора, чтобы решить эту проблему "курицы и яйца", но самый надёжный способ - это регистрировать функцию завершения, как описано выше.

Внимание

Текущий рабочий каталог изменяется некоторыми SAPI, если сессия закрывается при завершении скрипта. Завершить сессию можно раньше с помощью session_write_close().

Смотрите также