Sesión PHP expira en 30 minutos: 4 formas funcionales

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: «¿Por qué mi sesión no muere?»

\n\n

Imagine: está escribiendo una tienda en línea, un panel de administración o un área personal. El usuario inició sesión, trabajó, se fue a tomar un café — y una hora después su sesión sigue viva. Los datos del carrito están colgados, el acceso está abierto. Esto no solo es incómodo, sino también peligroso. Especialmente si el sitio trabaja con datos de pago.

\n\n

La pregunta «How do I expire a PHP session after 30 minutes?» es una de las más populares en Stack Overflow (decenas de miles de visitas). Y no es de extrañar: los desarrolladores principiantes a menudo piensan que basta con establecer session.gc_maxlifetime — y todo funcionará. Luego se sorprenden de por qué la sesión vive durante horas.

\n\n

En este artículo analizaremos 4 enfoques reales para hacer que una sesión PHP expire exactamente en 30 minutos. Aprenderá por qué la configuración estándar puede fallar y qué método elegir para su tarea. ¡Allá vamos!

\n\n

Un poco de teoría: cómo PHP gestiona el tiempo de sesión

\n\n

Antes de escribir código, es importante entender dos mecanismos que influyen en la «muerte» de la sesión:

\n\n
    \n
  • Tiempo de vida de la cookie de sesión — cuánto tiempo almacena el navegador el identificador de sesión (PHPSESSID). Se gestiona con el parámetro session.cookie_lifetime.
  • \n
  • Tiempo de vida de los datos en el servidor — cuánto tiempo permanece el archivo de sesión en la carpeta /tmp. Se gestiona con session.gc_maxlifetime.
  • \n
\n\n

El problema es que el recolector de basura (GC — garbage collector) se ejecuta de forma probabilística. Por defecto, se activa en el 1% de las solicitudes. Esto significa que incluso si gc_maxlifetime = 1800 (30 minutos), la sesión puede seguir viva otra hora hasta que el GC llegue a ella.

\n\n

Por lo tanto, confiar solo en la configuración del servidor es una mala idea. Es necesario verificar el tiempo «manualmente».

\n\n

Método n.º 1. Clásico: verificación del tiempo en la sesión (recomendado)

\n\n

Este es el método más fiable y transparente. Usted mismo almacena en la sesión una marca de tiempo de la última actividad y, en cada solicitud, verifica si han pasado 30 minutos.

\n\n
<?php\nsession_start();\n\n// Establecemos el tiempo de vida de la sesión — 30 minutos (1800 segundos)\n$timeout_duration = 1800;\n\n// Si hay una marca de tiempo en la sesión y está vencida\nif (isset($_SESSION['LAST_ACTIVITY']) && \n    (time() - $_SESSION['LAST_ACTIVITY']) > $timeout_duration) {\n    // Destruimos la sesión\n    session_unset();\n    session_destroy();\n    // Redirigimos a la página de inicio de sesión\n    header("Location: login.php?timeout=1");\n    exit;\n}\n\n// Actualizamos la marca de tiempo (si el usuario está activo)\n$_SESSION['LAST_ACTIVITY'] = time();\n?>
\n\n

Ventajas:

\n
    \n
  • Control absoluto: la sesión morirá exactamente después de 30 minutos de inactividad.
  • \n
  • No depende de la configuración de PHP ni del recolector de basura.
  • \n
  • Fácil de cambiar el tiempo para diferentes secciones del sitio (por ejemplo, panel de administración — 15 minutos, usuario — 60).
  • \n
\n\n

Desventajas:

\n
    \n
  • Es necesario agregar la verificación en cada página (o sacarla a un archivo de inicialización común).
  • \n
  • Si el usuario mantiene la página abierta pero no hace clic — la sesión morirá. Para algunos escenarios (formularios largos) esto es una desventaja.
  • \n
\n\n

Método n.º 2. Combinado: gc_maxlifetime + cookie_lifetime

\n\n

Si no desea escribir una verificación manual, puede intentar configurar PHP «de fábrica». Pero recuerde los matices.

\n\n
// Al inicio del script, antes de session_start()\n$lifetime = 1800; // 30 minutos\n\n// Establecemos el tiempo de vida de la cookie de sesión\nsession_set_cookie_params($lifetime);\n\n// Establecemos el tiempo máximo de vida de los datos en el servidor\nini_set('session.gc_maxlifetime', $lifetime);\n\n// Ahora iniciamos la sesión\nsession_start();
\n\n

Adicionalmente — para que el GC funcione más a menudo, se puede reducir la probabilidad de ejecución:

\n\n
ini_set('session.gc_probability', 1);\nini_set('session.gc_divisor', 1); // El GC se ejecutará en cada solicitud

Blogs

Book Recommendations