# session_set_save_handler

(PHP 4, PHP 5, PHP 7, PHP 8)

session_set_save_handler — Establece funciones de almacenamiento de sesiones a nivel de usuario

### Descripción

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

Desde PHP 5.4 es posible registrar el siguiente prototipo:

session_set_save_handler(SessionHandlerInterface `$sessionhandler`, bool `$register_shutdown` = true): bool

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.

### Parámetros

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().

o

`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.

`create_sid()`

  Esta retrollamada se ejecuta cuando se requiere un nuevo ID de sesión. No se proporcionan parámetros, y el valor devuelto debería ser un string que sea un ID de sesión válido para el gestor utilizado.

### Valores devueltos

Devuelve `true` en caso de éxito o `false` en caso de error.

### Ejemplos

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`

### Notas

Advertencia

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.

Advertencia

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.

Advertencia

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().

### Historial de cambios

Versión | Descripción
--- | ---
5.5.1 | Se añadió el parámetro opcional `create_sid`.
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.

### Ver también

- La directiva de configuración session.save_handler.
- La directiva de configuración session.serialize_handler.
- La función register_shutdown_function() - Registrar una función para que sea ejecutada al cierre
- La función session_register_shutdown() - Función de cierre de sesiones para PHP 5.4.0+