mirror of
https://github.com/php/doc-ru.git
synced 2025-07-28 06:39:58 +00:00
247 lines
11 KiB
XML
247 lines
11 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- EN-Revision: 62126c55f1c6ed444043e7272c4f9e233818a44b Maintainer: rjhdby Status: ready -->
|
||
<!-- Reviewed: no -->
|
||
<reference xml:id="class.sessionhandler" role="class" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude">
|
||
|
||
<title>Класс SessionHandler</title>
|
||
<titleabbrev>SessionHandler</titleabbrev>
|
||
|
||
<partintro>
|
||
|
||
<!-- {{{ SessionHandler intro -->
|
||
<section xml:id="sessionhandler.intro">
|
||
&reftitle.intro;
|
||
<para>
|
||
<classname>SessionHandler</classname> это специальный класс, который может использоваться для
|
||
дополнения внутреннего обработчика сессий PHP путём создания дочерних классов от этого.
|
||
Существует семь методов, которые являются обёртками над семью внутренними обработчиками хранения
|
||
данных сессии (<parameter>open</parameter>, <parameter>close</parameter>, <parameter>read</parameter>,
|
||
<parameter>write</parameter>, <parameter>destroy</parameter>, <parameter>gc</parameter> и
|
||
<parameter>create_sid</parameter>). По умолчанию этот класс оборачивает все внутренние
|
||
обработчики хранения сессии, определённые в опции конфигурации <link linkend="ini.session.save-handler">session.save_handler</link>.
|
||
Эта опция по умолчанию имеет значение <parameter>files</parameter>.
|
||
Другие внутренние обработчики сессий предоставляются PHP-модулями, такими как
|
||
SQLite (<parameter>sqlite</parameter>), Memcache (<parameter>memcache</parameter>)
|
||
и Memcached (<parameter>memcached</parameter>).
|
||
</para>
|
||
<para>
|
||
Экземпляр класса <classname>SessionHandler</classname> может устанавливаться в
|
||
качестве обработчика сессии посредством вызова функции <function>session_set_save_handler</function>.
|
||
В этом случае он станет обёрткой существующего внутреннего обработчика.
|
||
Классы, расширяющие <classname>SessionHandler</classname> позволят переопределить
|
||
методы обработчика сессии или перехватить/отфильтровать их путём вызова
|
||
родительских методов-обёрток внутреннего обработчика сессий PHP.
|
||
</para>
|
||
<para>
|
||
Это позволит вам, к примеру, перехватить методы <parameter>read</parameter> и
|
||
<parameter>write</parameter> для шифровки/дешифровки данных сессии и передачи
|
||
результата родительскому классу и от него. Или, к примеру, вы можете полностью
|
||
переопределить такой метод как callback-функция сборщика мусора (<parameter>gc</parameter>).
|
||
</para>
|
||
<para>
|
||
Так как <classname>SessionHandler</classname> является обёрткой над стандартным
|
||
внутренним обработчиком сессии, то пример, приведённый выше про шифровку данных
|
||
может быть применён к любому внутреннему обработчику сессии даже без понимания
|
||
внутреннего устройства процесса работы сессии.
|
||
</para>
|
||
<para>
|
||
Для использования этого класса, во-первых, установите обработчик, который вы хотите
|
||
дополнить используя <link linkend="ini.session.save-handler">session.save_handler</link>.
|
||
Далее передайте экземпляр класса <classname>SessionHandler</classname> или одного из
|
||
классов, расширяющих его функции <function>session_set_save_handler</function>.
|
||
</para>
|
||
<para>
|
||
Обратите внимание, что callback-методы этого класса предназначены для внутреннего вызова PHP
|
||
и не предназначены для вызова из кода пользовательского пространства.
|
||
Возвращаемые значения одинаково обрабатываются внутри PHP.
|
||
Дополнительную информацию о работе с сессией можно узнать
|
||
из описания функции <function>session_set_save_handler</function>.
|
||
</para>
|
||
</section>
|
||
<!-- }}} -->
|
||
|
||
<section xml:id="sessionhandler.synopsis">
|
||
&reftitle.classsynopsis;
|
||
|
||
<!-- {{{ Synopsis -->
|
||
<classsynopsis class="class">
|
||
<ooclass>
|
||
<classname>SessionHandler</classname>
|
||
</ooclass>
|
||
|
||
<oointerface>
|
||
<modifier>implements</modifier>
|
||
<interfacename>SessionHandlerInterface</interfacename>
|
||
</oointerface>
|
||
|
||
<oointerface>
|
||
<interfacename>SessionIdInterface</interfacename>
|
||
</oointerface>
|
||
|
||
<classsynopsisinfo role="comment">&Methods;</classsynopsisinfo>
|
||
<xi:include xpointer="xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.sessionhandler')/db:refentry/db:refsect1[@role='description']/descendant::db:methodsynopsis[@role='SessionHandler'])">
|
||
<xi:fallback/>
|
||
</xi:include>
|
||
</classsynopsis>
|
||
<!-- }}} -->
|
||
|
||
</section>
|
||
|
||
<section xml:id="session.notes">
|
||
&reftitle.notes;
|
||
<warning>
|
||
<para>
|
||
Этот класс предназначен для расширения текущего внутреннего обработчика сессии PHP.
|
||
При этом, если вам нужно написать собственный обработчик, то необходимо написать
|
||
собственную реализацию интерфейса <classname>SessionHandlerInterface</classname>
|
||
вместо расширения класса <classname>SessionHandler</classname>.
|
||
</para>
|
||
</warning>
|
||
</section>
|
||
|
||
<section xml:id="sessionhandler.examples">
|
||
&reftitle.examples;
|
||
<example>
|
||
<title>
|
||
Пример использования класса <classname>SessionHandler</classname> для добавления
|
||
шифрования внутренним обработчикам сохранения PHP
|
||
</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
/**
|
||
* Расшифровать данные алгоритмом AES 256
|
||
*
|
||
* @param data $edata
|
||
* @param string $password
|
||
* @return расшифрованные данные
|
||
*/
|
||
function decrypt($edata, $password) {
|
||
$data = base64_decode($edata);
|
||
$salt = substr($data, 0, 16);
|
||
$ct = substr($data, 16);
|
||
|
||
$rounds = 3; // Зависит от длины ключа
|
||
$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);
|
||
}
|
||
|
||
/**
|
||
* Зашифровать данные алгоритмом AES 256
|
||
*
|
||
* @param data $data
|
||
* @param string $password
|
||
* @return base64 зашифрованные данные
|
||
*/
|
||
function encrypt($data, $password) {
|
||
// Генерация криптографически безопасной случайной соли функцией random_bytes()
|
||
$salt = random_bytes(16);
|
||
|
||
$salted = '';
|
||
$dx = '';
|
||
// Ключ соли (32) и вектор инициализации (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
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
<note>
|
||
<para>
|
||
Поскольку методы этого класса предназначены для внутренних вызовов из PHP как часть
|
||
нормального процесса работы сессий, вызовы родительских методов из дочернего класса
|
||
(иными словами «родных» обработчиков) будет возвращать &false; до тех пор,
|
||
пока сессия не будет запущена (автоматически или прямым вызовом функции <function>session_start</function>).
|
||
Это важный момент для понимания, особенно при тестировании, где методы класса
|
||
могут вызываться вручную.
|
||
</para>
|
||
</note>
|
||
</section>
|
||
|
||
</partintro>
|
||
|
||
&reference.session.entities.sessionhandler;
|
||
|
||
</reference>
|
||
<!-- Keep this comment at the end of the file
|
||
Local variables:
|
||
mode: sgml
|
||
sgml-omittag:t
|
||
sgml-shorttag:t
|
||
sgml-minimize-attributes:nil
|
||
sgml-always-quote-attributes:t
|
||
sgml-indent-step:1
|
||
sgml-indent-data:t
|
||
indent-tabs-mode:nil
|
||
sgml-parent-document:nil
|
||
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
||
sgml-exposed-tags:nil
|
||
sgml-local-catalogs:nil
|
||
sgml-local-ecat-files:nil
|
||
End:
|
||
vim600: syn=xml fen fdm=syntax fdl=2 si
|
||
vim: et tw=78 syn=sgml
|
||
vi: ts=1 sw=1
|
||
-->
|