(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
)
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().
Этот класс предназначен для расширения текущего внутреннего обработчика сессии PHP. При этом, если Вам нужно написать собственный обработчик, то необходимо написать собственную реализацию интерфейса SessionHandlerInterface вместо расширения класса SessionHandler.
Пример #1 Использвание SessionHandler для того, чтобы добавить шифровку данных ко внутреннему обработчику сессий PHP.
<?php
/**
* decrypt AES 256
*
* @param data $edata
* @param string $password
* @return decrypted data
*/
function decrypt($edata, $password) {
$data = base64_decode($edata);
$salt = substr($data, 0, 16);
$ct = substr($data, 16);
$rounds = 3; // depends on key length
$data00 = $password.$salt;
$hash = array();
$hash[0] = hash('sha256', $data00, true);
$result = $hash[0];
for ($i = 1; $i < $rounds; $i++) {
$hash[$i] = hash('sha256', $hash[$i - 1].$data00, true);
$result .= $hash[$i];
}
$key = substr($result, 0, 32);
$iv = substr($result, 32,16);
return openssl_decrypt($ct, 'AES-256-CBC', $key, true, $iv);
}
/**
* crypt AES 256
*
* @param data $data
* @param string $password
* @return base64 encrypted data
*/
function encrypt($data, $password) {
// Set a random salt
$salt = openssl_random_pseudo_bytes(16);
$salted = '';
$dx = '';
// Salt the key(32) and iv(16) = 48
while (strlen($salted) < 48) {
$dx = hash('sha256', $dx.$password.$salt, true);
$salted .= $dx;
}
$key = substr($salted, 0, 32);
$iv = substr($salted, 32,16);
$encrypted_data = openssl_encrypt($data, 'AES-256-CBC', $key, true, $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($handler, true);
session_start();
// устанавливаем и получаем значения из $_SESSION
Замечание:
Так как методы этого класса предназначены для внутренних вызовов из PHP, как часть нормального процесса работы сессий, вызовы родительских методов из дочернего класса (иными словами "родных" обработчиков) будет возвращать
FALSE
до тех пор, пока сессия не будет запущена (автоматически или прямым вызовом session_start()). Это важный момент для понимания, особенно при тестировании, где методы класса могут быть вызваны вручную.