(PHP 4, PHP 5)
session_set_save_handler — Establece funciones de almacenamiento de sesiones a nivel de usuario
$open
, callable $close
, callable $read
, callable $write
, callable $destroy
, callable $gc
)Desde PHP 5.4 es posible registrar el siguiente prototipo:
$sessionhandler
[, bool $register_shutdown
= true
] )session_set_save_handler() establece las funciones de almacenamiento de sesiones a nivel de usuario que se usan para almacenar y recuperar información asociada con una sesión. Es más útil cuando se prefiere un método de almacenamiento distinto de aquellos proporcionados por las sesiones de PHP. Esto es, almacenar la información de sesión en una base de datos local.
Esta función tiene dos prototipos.
sessionhandler
Una instancia de una clase que implemente SessionHandlerInterface, tal como SessionHandler, para registrarla como el gestor de sesión. Sólo desde PHP 5.4.
register_shutdown
Registrar la función session_write_close() como una función register_shutdown_function().
open(string $savePath, string $sessionName)
La llamada de retorno open funciona como un constructor en las clases y es
ejecutada cuando la sesión está siendo abierta. Es la primera función de llamada
de retorno ejecutada cuando la sesión se inicia automáticamente o
manualmente con session_start().
El valor devuelto es TRUE
en caso de éxito, FALSE
en caso de error.
close()
La llamada de retorno close funciona como un destructor en las clases y es
ejecutada después de haber llamado a la llamada de retorno write de la sesión. También se invoca cuando
se llama a session_write_close().
El valor devuelto debería ser TRUE
en caso de éxito, FALSE
en caso de error.
read(string $sessionId)
La llamada de retorno read
debe devolver siempre una cadena de sesión
(serializada), o una cadena vacía si no existe información que leer.
Esta llamada de retorno es llamda internamente por PHP cuando se inicia la sesión o
cuando se llama a session_start(). Antes de invocar a esta llamada de sesión
PHP invocará a la llamda de retorno open
.
El valor que devuelve esta llamada de retorno debe estar exactamente en el mismo formato de serialización que fue originalmente
pasado para el almacenamiento de la llamada de retorno write
. El valor devuelto será deserializado
automáticamente por PHP y srá usado para rellenar la variable superglobal $_SESSION.
Aunque la información parezca similar a serialize(), observe que está en un formato diferente,
el cual está especificado en la configuración ini session.serialize_handler.
write(string $sessionId, string $data)
La llamada de retorno write
es llamada cuando la sesión necesita ser almacenada y cerrada. Esta
llamada de retorno recibe el ID de sesión actual, una versión serializada de la variable superglobal $_SESSION. El método de
serialización usado internamente por PHP está especificado en la configuración ini session.serialize_handler.
La información serializada de sesión pasada a esta llamada de retorno debería ser almacenada junto con el ID de sesión pasado. Al recuperar
esta información, la llamada de retorno read
debe devolver el valor exacto que fue pasado originalmente a
la llamda de retorno write
.
Esta llamada de retorno es invocada cuando PHP se cierra o cuando se llamda explícitamente a
session_write_close(). Observe que después de ejecutar esta función PHP ejecutará internamente la llamada de retorno close
.
Nota:
El gestor "write" no se ejecuta hasta después de que se cierre el flujo de salida. Así, la salida desde declaraciones de depuración en el gestor "write" nunca serán vistas en el navegador. Si es necesaria la salida de depuración, se sugiere que la salida de depuración sea escrita en un archivo en su lugar.
destroy($sessionId)
Esta llamada de retorno es ejecutada cuando una sesión es destruida con session_destroy() o con
session_regenerate_id() con el parámetro destroy establecido en TRUE
.
El valor devuelto debería ser TRUE
en caso de éxito, FALSE
en caso de error.
gc($lifetime)
La llamada de retorno del recolector de basura (Garbage Collector) es invocada internamente por PHP de manera periódica para
destruir información antigua de sesiones. La frecuencia es controlada por
session.gc_probability y session.gc_divisor.
El valor del tiempo de vida (lifetime) que es pasado a esta llamada de retorno puede establecerse en session.gc_maxlifetime.
El valor devuelto debería ser TRUE
en caso de éxito, FALSE
en caso de error.
Devuelve TRUE
en caso de éxito o FALSE
en caso de error.
Ejemplo #1 Gestor de seseiones personalizado: véase el código completo en la sinopsis de SessionHandlerInterface.
El siguiente código es para la versión 5.4.0 y superiror de PHP. Aquí se muestra la invocación, el código completo puede verse en la sinopsis de SessionHandlerInterface vinculada más arriba.
Observe que usamos el prototipo de POO con session_set_save_handler() y registramos la función de cierre usando la bandera de parámetro de la función. Esto se recomienda generalmente al registrar objetos como gestores de almacenamiento de sesiones.
<?php
class MySessionHandler implements SessionHandlerInterface
{
// implementar las interfaces aquí
}
$handler = new MySessionHandler();
session_set_save_handler($handler, true);
session_start();
// proceder a estblecer y recuperar valores mediante clave desde $_SESSION
Ejemplo #2 Gestor de almacenamiento de sesiones personalizado usando objetos
El siguiente código es para versiones de PHP inferiores a 5.4.0.
El siguiente ejemplo proporciona un almacenamiento de sesiones basado en fichero similar al
gestor de almacenamiento de sesiones de PHP predeterminado files
. Este
ejemplo podría extenderse fácilmente para cubrir el almacenamiento de bases de datos usando su
motor de bases de datos favorito soportado por PHP.
Observe que registramos de forma adicional la función de cierre session_write_close() usando register_shutdown_function() bajo PHP inferior a 5.4.0. Esto se recomienda generalmente al registrar objetos como gestores de almacenamiento de sesiones bajo PHP inferior a 5.4.0.
<?php
class FileSessionHandler
{
private $savePath;
function open($savePath, $sessionName)
{
$this->savePath = $savePath;
if (!is_dir($this->savePath)) {
mkdir($this->savePath, 0777);
}
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')
);
// lo siguiente previene de efectos inesperados al usar objetos como gestores de almacenamiento
register_shutdown_function('session_write_close');
session_start();
// proceder para establecer y recuperar valores por clave desde $_SESSION
Cuando se usan objetos como gestores de almacenamiento de sesionea es importante registrar la
función de cierre con PHP para evitar efectos secundarios inesperados ya que
PHP internamente destruye objetos en el cierre y puede prevenir que
write
y close
sean llamados.
Normalmente se debería registrar 'session_write_close'
usando la
función register_shutdown_function().
A partir de PHP 5.4.0 se puede usar session_register_shutdown() o simplemente la bandera 'register shutdown' al invocar session_set_save_handler() usando el método de POO the OOP y pasando una instancia que implemente SessionHandlerInterface.
A partir de PHP 5.0.5 los gestores write
y
close
son llamados después de la destrucción
del objeto y por lo tanto no pueden usar objetos o lanzar excepciones.
Las excepciones no pueden ser capturadas ya que no serán capturadas ni
cualquier rastro de excepción será mostrado y la ejecución se interrumpirá de improviso.
Sin embargo, los destructores de objetos pueden usar sesiones.
Es posible llamar a session_write_close() desde el destructor para solucionar este problema de "quién fue antes, si el huevo o la gallina" pero la forma más fiable es registrar la función de ceirre como está descrito más arraba.
El directorio de trabajo actual es cambiado en algunas SAPI si la sesión se cierra al finalizar el script. Es posible cerrar la sesión antes con session_write_close().
Versión | Descripción |
---|---|
5.4.0 | Se añadió SessionHandlerInterface para la implementación de gestores de sesión y SessionHandler para exponer gestores de sesión internos de PHP. |