PHP, Sesiones · 2 min read · Dec 27, 2025

Los datos de sesión de PHP no se eliminan al usar gestión de sesiones personalizada en debian (y ubuntu)

En sistemas debian (hasta donde sé, esto también se aplica a ubuntu) el recolector de basura para sesiones de PHP está deshabilitado por defecto.

La configuración correspondiente en php.ini es session.gc_probability = 0 que habilita el recolector de basura cuando se establece en algo mayor que cero. El valor predeterminado en PHP es 1, por lo que el recolector de basura se llama con una probabilidad de 1/100 en cada llamada de script PHP.

En sistemas debian, esta configuración está deshabilitada debido al hecho de que la ruta predeterminada para el almacenamiento de sesiones no es escribible para el proceso del servidor web (y no debería serlo tampoco). La eliminación de archivos de sesión obsoletos se realiza aquí mediante un trabajo cron del sistema.

A continuación, un extracto del php.ini:

; Esto está deshabilitado en los paquetes de Debian, debido a los permisos estrictos
; en /var/lib/php5.  En lugar de establecer esto aquí, consulte el trabajo cron en
; /etc/cron.d/php5, que utiliza la configuración session.gc_maxlifetime a continuación.
; Los scripts php que utilizan su propio session.save_path deben asegurarse de que la recolección de
; basura esté habilitada estableciendo session.gc_probability
;session.gc_probability = 0

Como esta configuración está bien para scripts que utilizan el manejo de sesiones predeterminado de php (archivo), esto puede llevar a problemas cuando usas tu propio manejo de sesiones que define sus propias rutinas para la lectura y escritura de sesiones utilizando session_save_handler(). Esas clases de gestión de sesiones proporcionarán una función propia para el recolector de basura, también en la mayoría de los casos.

El problema es que esta función del recolector de basura nunca se llamará en un sistema debian con la configuración de php.ini mencionada anteriormente. Esto es crucial, cuando los datos de sesión se almacenan en una base de datos MySQL de tipo MEMORY. Esta tabla está limitada en tamaño por el valor de configuración de MySQL max_heap_table_size. Si se alcanza este tamaño, todas las escrituras de sesión posteriores fallarán y con ello probablemente el sitio web dejará de funcionar correctamente.

Sabiendo esto, es realmente importante sobrescribir la configuración de php.ini para la recolección de basura en tu propia clase de gestión de sesiones. Mostraré esto con un pequeño ejemplo de una clase de gestión de sesiones (sin escritura/lectura real):

class session {
    function __destruct() {
        session_write_close();
    }
    function __construct() {
        @ini_set("session.use_trans_sid","0");
        @ini_set('session.gc_probability', 1); // en debian esto está deshabilitado por defecto...
         
        // habilitar funciones de manejador de sesión personalizadas
        session_set_save_handler(array(&$this,"_sess_open"),
                                 array(&$this,"_sess_close"),
                                 array(&$this,"_sess_read"),
                                 array(&$this,"_sess_write"),
                                 array(&$this,"_sess_destroy"),
                                 array(&$this,"_sess_gc"));
        @session_start();
    }
 
    // declarar funciones de manejador de sesión definidas por el usuario
    function _sess_open($sSavePath, $sSessionName) {
        return true;
    }
     
    function _sess_close() {
        return true;
    }
     
    function _sess_read($sKey) {
        // leer y devolver valor
    }
     
    function _sess_write($sKey, $val) {
        // escribir nuevo valor
    }
     
    function _sess_destroy($sKey) {
        // destruir sesión
    }
     
    function _sess_gc($iMaxLifeTime) {
        // eliminar sesiones antiguas (de la db)
    } 
}
 
$mySession = new session();

Lo importante es la llamada de @ini_set(‘session.gc_probability’, 1) dentro del constructor. Después de esto, la recolección de basura de sesiones debería funcionar como se espera, incluso en sistemas debian con tu propia clase de gestión de sesiones.

Share: X/Twitter LinkedIn

Recibe nuevas publicaciones en tu bandeja de entrada.

No spam. Cancela la suscripción en cualquier momento.