Hoy vamos a ver cómo evitar que una sesión de PHP expire, es decir, prevenir o evitar la expiración de una sesión en PHP.
Para ello vamos a usar un poco de JavaScript.
La lógica
Sin importar si cambiamos el valor de session.gc_maxlifetime
la sesión siempre va a expirar si el usuario no refresca la página o la sesión por determinado tiempo.
Por ejemplo, puede haber un formulario que debe llenarse en el transcurso del día, si se inicia sesión al inicio, cuando se quiera enviar al final del día la sesión habrá expirado y el trabajo estará perdido.
Para evitar que una sesión expire debemos estar refrescándola, esto es, hacer que el usuario refresque una página o ejecuta un script de PHP cada cierto tiempo para indicar que “sigue ahí”.
Como no podemos hacer que nuestros usuarios lo hagan manualmente podemos usar JavaScript para que haga peticiones AJAX en segundo plano cada determinado tiempo, y en esa petición refrescar la sesión. De esa forma la sesión no se cierra por inactividad.
Evitar expiración de sesión en PHP
Antes de todo, el usuario debe haber iniciado sesión ya sea desde un formulario de login o desde cualquier otro lugar.
Comencemos. Primero debemos tener un script que llame a session_start()
para refrescar la sesión; puedes comprobar si la sesión no está iniciada, o usar @
para silenciar errores de que la sesión ya se había iniciado.
En este caso para fines prácticos lo haré con @
para silenciar errores así que:
<?php
@session_start();
# Eso es todo, ahora solo hay que llamar a este archivo cada cierto tiempo
Ahora en cada página o en la página en donde el usuario estará sin mover otra cosa que reinicie la sesión, debemos hacer que un script de JS haga una petición HTTP al archivo de PHP cada cierto tiempo.
Para ejecutar algo cada cierto tiempo usamos setInterval, y para las peticiones HTTP se pueden usar varias cosas, por ejemplo fetch, que es una función nativa y moderna.
Por lo tanto, cada 5 segundos visitamos al script:
document.addEventListener("DOMContentLoaded", function(){
// Invocamos cada 5 segundos ;)
const milisegundos = 5 *1000;
setInterval(function(){
// No esperamos la respuesta de la petición porque no nos importa
fetch("./refrescar.php");
},milisegundos);
});
Y ese script lo colocamos dentro de una página PHP o HTML:
<?php
?><!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Mi página web</title>
</head>
<body>
<p>Aquí el usuario puede tardar lo que quiera, su sesión no se va a
cerrar por inactividad</p>
<script>
document.addEventListener("DOMContentLoaded", function(){
// Invocamos cada 5 segundos ;)
const milisegundos = 5 *1000;
setInterval(function(){
// No esperamos la respuesta de la petición porque no nos importa
fetch("./refrescar.php");
},milisegundos);
});
</script>
</body>
</html>
Si notas que incluí las etiquetas en el encabezado fue para que se reconociera la sintaxis. Con eso es suficiente. Con este enfoque, cada 5 segundos se estará abriendo el archivo refrescar.php, lo que será como si el usuario estuviera navegando activamente, evitando la expiración de la sesión.
En las herramientas de depuración de Chrome se pueden ver las peticiones, lo cual demuestra que efectivamente el script de PHP que refresca la sesión está siendo invocado:
Recuerda que puedes cambiar el intervalo de tiempo, incluso con 5 minutos quedaría bien.
Excelente aporte amigo, me sirvio de mucho. Saludos.
Hice un pequeño módulo y siempre tenía el mismo problema con la sesión 🙁 Ahora gracias a su ayuda ya trabaja bien. Muchísimas gracias y bendiciones.
Gracias por sus comentarios, me agrada escuchar que mi post le haya funcionado. Le invito a compartir y suscribirse
Saludos!
Le gradezco mucho su ayuda. Hice un pequeño módulo y tenía el mismo problema… siempre se terminaba cerrando la sesión :(. Pero con su ayuda lo solucioné. Muchísimas gracias.
Yo tengo una duda, si visita la pagina, la visita en segundo plano?
Hola. Así es, en el inicio indico que con AJAX se visita de manera asíncrona y en segundo plano. El usuario ni siquiera lo nota
Saludos 🙂
Gracias me sirvió de mucho llevaba un buen tiempo intentando encontrar una solución. 😀
Si el post fue de su agrado le invito a compartirlo y seguirme
Saludos 🙂
Llevo con este problema por meses y voy a usar esta solucion gracias.
Ahora mi pregunta como sabemos cuanto dura la sestion para no tener que hacerlo cada 5 segundos y poder extenderlo un poco mas.?
Gracias.
Hola. No es necesario hacerlo cada N segundos, podría usted probar cada 10 minutos por ejemplo. Encontré algo de información aquí: https://www.php.net/manual/es/session.configuration.php#ini.session.cookie-lifetime
Gracias amigo , me fue de mucha utilidad ! no sabía por que se me cerraba la sesión, gracias a esto lo solucioné.