Класс SessionHandler

(PHP 5 >= 5.4.0, PHP 7)

Введение

SessionHandler это специальный класс, который может использоваться для дополнения внутреннего обработчика сессий PHP путем создания дочерних классов от этого. Существует семь методов, которые являются обертками над семью внутренними обработчиками хранения данных сессии (open, close, read, write, destroy, gc и create_sid). По умолчанию этот класс оборачивает все внутренние обработчики хранения сессии, определенные в опции конфигурации session.save_handler. Эта опция по умолчанию имеет значение files. Другие внутренние обработчики сессий предоставляются PHP-расширениями, такими как SQLite (sqlite), Memcache (memcache) и Memcached (memcached).

Экземпляр класса SessionHandler может устанавливаться в качестве обработчика сессии посредством вызова функции session_set_save_handler(). В этом случае он станет оберткой существующего внутреннего обработчика. Классы, расширяющие SessionHandler позволят переопределить методы обработчика сессии или перехватить/отфильтровать их путем вызова родительских методов-оберток внутреннего обработчика сессий PHP.

Это позволит вам, к примеру, перехватить методы read и write для шифровки/дешифровки данных сессии и передачи результата родительскому классу и от него. Или, к примеру, вы можете полностью переопределить такой метод как callback-функция сборщика мусора (gc).

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

Для использования этого класса, во-первых, установите обработчик, который вы хотите дополнить используя session.save_handler. Далее передайте экземпляр класса SessionHandler или одного из классов, расширяющих его функции session_set_save_handler().

Обратите внимание, что методы этого класса предназначены для внутреннего вызова из PHP. Вызывать их из своего кода не нужно. Дополнительную информацию о работе сессии можно узнать из описания функции session_set_save_handler().

Обзор классов

SessionHandler implements SessionHandlerInterface , SessionIdInterface {
/* Методы */
public close ( ) : bool
public create_sid ( ) : string
public destroy ( string $id ) : bool
public gc ( int $max_lifetime ) : int|bool
public open ( string $path , string $name ) : bool
public read ( string $id ) : string
public write ( string $id , string $data ) : bool
}
Внимание

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

Список изменений

Версия Описание
5.5.1 Добавлено SessionHandler::create_sid().

Пример #1 Использвание SessionHandler для того, чтобы добавить шифровку данных ко внутреннему обработчику сессий PHP.

<?php

 
/**
  * расшифровать данные, используя алгоритм AES 256
  *
  * @param data $edata
  * @param string $password
  * @return расшифрованные данные
  */
function decrypt($edata$password) {
    
$data base64_decode($edata);
    
$salt substr($data016);
    
$ct substr($data16);

    
$rounds 3// зависит от длины ключа
    
$data00 $password.$salt;
    
$hash = array();
    
$hash[0] = hash('sha256'$data00true);
    
$result $hash[0];
    for (
$i 1$i $rounds$i++) {
        
$hash[$i] = hash('sha256'$hash[$i 1].$data00true);
        
$result .= $hash[$i];
    }
    
$key substr($result032);
    
$iv  substr($result32,16);

    return 
openssl_decrypt($ct'AES-256-CBC'$keytrue$iv);
  }

/**
 * зашифровать данные алгоритмом AES 256
 *
 * @param data $data
 * @param string $password
 * @return base64 зашифрованные данные
 */
function encrypt($data$password) {
    
// Установить случайную соль
    
$salt openssl_random_pseudo_bytes(16);

    
$salted '';
    
$dx '';
    
// Ключ соли (32) и вектор инициализации (16) = 48
    
while (strlen($salted) < 48) {
      
$dx hash('sha256'$dx.$password.$salttrue);
      
$salted .= $dx;
    }

    
$key substr($salted032);
    
$iv  substr($salted32,16);

    
$encrypted_data openssl_encrypt($data'AES-256-CBC'$keytrue$iv);
    return 
base64_encode($salt $encrypted_data);
}

class 
EncryptedSessionHandler extends SessionHandler
{
    private 
$key;

    public function 
__construct($key)
    {
        
$this->key $key;
    }

    public function 
read($id)
    {
        
$data parent::read($id);

        if (!
$data) {
            return 
"";
        } else {
            return 
decrypt($data$this->key);
        }
    }

    public function 
write($id$data)
    {
        
$data encrypt($data$this->key);

        return 
parent::write($id$data);
    }
}

// Здесь мы перехватываем встроенный обработчик 'files', но можно использовать любой другой
// обработчик, например 'sqlite', 'memcache' или 'memcached',
// которые предоставлены расширениями PHP.
ini_set('session.save_handler''files');

$key 'secret_string';
$handler = new EncryptedSessionHandler($key);
session_set_save_handler($handlertrue);
session_start();

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

Замечание:

Так как методы этого класса предназначены для внутренних вызовов из PHP, как часть нормального процесса работы сессий, вызовы родительских методов из дочернего класса (иными словами "родных" обработчиков) будет возвращать false до тех пор, пока сессия не будет запущена (автоматически или прямым вызовом session_start()). Это важный момент для понимания, особенно при тестировании, где методы класса могут быть вызваны вручную.

Содержание