2009-08-06 29 views
33

¿Cuál es la diferencia real entre session.gc_maxlifetime y session_cache_expire()?Tiempos de espera de sesión en PHP: mejores prácticas

Supongamos que deseo que la sesión de los usuarios sea inválida después de 15 minutos de inactividad (y no 15 después de que se abrió por primera vez). ¿Cuál de estos me ayudará allí?

También sé que puedo hacer session_set_cookie_params() que puede configurar la cookie del usuario para que caduque en un cierto período de tiempo. Sin embargo, la cookie que expira y la sesión actual que expira en el servidor no son lo mismo; ¿Esto también elimina la sesión cuando la cookie ha expirado?

Otra solución que tengo, aunque es simple de $_SESSION['last_time'] = time() en cada petición, y la comparación de la sesión a la hora actual, la supresión de la sesión basado en eso. Esperaba que hubiera un mecanismo más "incorporado" para manejar esto.

Gracias.

+0

Como me topé con esta pregunta a mí mismo después de algunas investigaciones, uno puede tener una respuesta muy a fondo sobre ese problema en [esta pregunta StackOverflow] (http://stackoverflow.com/a/1270960/474526), ​​especialmente por qué ninguna actualización de 'session.gc_maxlifetime' ni 'session.cookie_lifetime' son enfoques confiables. –

Respuesta

39

Cada vez que se llama session_start a la fecha y hora de los archivos de sesión (si existe) se actualiza, que se usa para calcular si se ha excedido session.gc_maxlifetime.

Lo que es más importante, no puede depender de que una sesión caduque después de que se haya excedido el tiempo de la sesión.gc_maxl.

PHP ejecuta la recolección de basura en las sesiones vencidas después de que se carga la sesión actual y mediante el uso de session.gc_probability y session.gc_divisor se calcula la probabilidad de que se ejecute la recolección de elementos no utilizados. Por defecto es un 1% de probabilidad.

Si tiene un número bajo de visitantes, hay una probabilidad de que un usuario inactivo pueda acceder a una sesión que debería haber caducado y eliminado. Si esto es importante, deberá almacenar una marca de tiempo en la sesión y calcular cómo ha estado inactivo un usuario.

En este ejemplo se reemplaza session_start y hace cumplir un tiempo de espera:

function my_session_start($timeout = 1440) { 
    ini_set('session.gc_maxlifetime', $timeout); 
    session_start(); 

    if (isset($_SESSION['timeout_idle']) && $_SESSION['timeout_idle'] < time()) { 
     session_destroy(); 
     session_start(); 
     session_regenerate_id(); 
     $_SESSION = array(); 
    } 

    $_SESSION['timeout_idle'] = time() + $timeout; 
} 
5

session.gc_maxlifetime se basa en la última vez que se modificó un archivo de sesión. Por lo tanto, cada vez que se modifica un archivo de sesión o se llama a session_start() en una página separada, la cuenta atrás para gc_maxlifetime comienza de nuevo y el usuario permanece "conectado". Este es el valor que está buscando. Puede modificar esto a través de ini_set() en sus archivos php, o editar php.ini si tiene acceso a ella

session_cache_expire() sólo controla el HTTP "expira" de cabecera. Este encabezado controla cuánto tiempo permanecen los contenidos de la página descargada en el caché del navegador del usuario.

49

pasé algún tiempo en busca de una buena respuesta a la forma en la configuración del servidor de php.ini hacen sesiones expiran. Encontré mucha información, pero me tomó un tiempo averiguar por qué la configuración funciona de la manera en que lo hacen. Si eres como yo, esto podría ser útil para ti:

Las sesiones se almacenan como cookies (archivos en la PC del cliente) o del lado del servidor como archivos en el servidor. Ambos métodos tienen ventajas y desventajas.

Para las sesiones almacenadas en el servidor, se utilizan tres variables.

session.gc_probability session.gc_divisor session.gc_maxlifetime

(session.gc_probability/session.gc_divisor) produce la probabilidad de que la rutina de colección basura se ejecutará. Cuando se ejecuta el recolector de elementos no utilizados, comprueba los archivos de sesión a los que no se ha accedido durante al menos session.gc_maxlifetime y los elimina.

Todo esto es explicado bastante bien en mensajes en el foro (sobre todo éste!) - Pero los siguientes preguntas vienen arriba:

1.) ¿Cómo se aplica esa probabilidad? ¿Cuándo tira el servidor los dados?

A: El servidor lanza los dados cada vez que se invoca session_start() durante cualquier sesión activa en el servidor. Así que esto significa que usted debe ver la basura plazo colector aproximadamente una vez por cada 100 veces que session_start() se llama si tiene el defecto de session.gc_probability = 1 y session.gc_divisor = 100

2.) ¿Qué ocurre en servidores de bajo volumen?

A: Cuando se llama a session_start(), FIRST actualiza la sesión y pone a su disposición los valores de sesión . Esto actualiza la hora en su archivo de sesión en el servidor . ENTONCES tira los dados y si gana (1 de cada 100 posibilidades) llama al recolector de basura. El recolector de elementos no utilizados luego verifica todos los archivos de id. De sesión y ve si hay cualquiera que sea elegible para eliminación.

Esto significa que si usted es la única persona en el servidor, su sesión nunca pasará a estar inactiva y parecerá que cambiar la configuración no tiene efecto . Supongamos que cambia session.gc_maxlifetime a 10 y session.gc_probability a 100. Esto significa que hay un 100% de posibilidades de que el recolector de elementos no utilizados se ejecute y eliminará los archivos de sesión a los que no se haya accedido en los últimos 10 segundos .

Si usted es el único en el servidor, su sesión no será eliminada. Necesita al menos 1 sesión activa más para que la suya quede inactiva.

Así que, básicamente, en un servidor de bajo volumen o en un momento bajo volumen - Podría ser mucho más largo que session.gc_maxlifetime antes de que el recolector de basura funciona realmente y las sesiones se elimina realmente. Y sin saber cómo funciona esto, puede aparecer completamente al azar para usted.

3.) ¿Por qué usan la probabilidad?

A: Rendimiento. En un servidor de mayor volumen, no desea que el recolector de elementos no utilizados se ejecute en cada solicitud de session_start(). Se ralentizará el servidor innecesariamente. Por lo tanto, dependiendo del volumen de su servidor, es posible que desee aumentar o disminuir la probabilidad de que se ejecute el recolector de elementos no utilizados.

Espero que esto una las cosas para usted. Si eres como yo y probaste la sesión .gc_maxlifetime y parece que no funcionó (porque lo intentó en un servidor de desarrollo para no molestar a nadie), entonces esta publicación con suerte le guardó algunos arañazos en la cabeza.

¡Buena suerte!

+3

¡Respuesta muy informativa! Debería estar en los documentos oficiales de PHP. ¡Gracias! –

+0

Respuesta muy clara ... pero me gustaría señalar que incluso si usa las sesiones predeterminadas basadas en archivos de PHP, aún se envía una cookie al navegador del usuario. Esta es una cookie de sesión (tradicionalmente caducan cuando cierran la pestaña/ventana) y simplemente contiene su identificador de sesión. Así que los "problemas" de la sesión pueden no estar limitados a la configuración del servidor. Si el navegador del usuario está 'recordando' esta cookie más allá de la pestaña/ventana, podrían perder sesiones que de otro modo esperarían conservar. Del mismo modo, jugar con la configuración de esta cookie podría afectar su capacidad para mantener viva una sesión. – simonhamp

+0

de http://www.appnovation.com/blog/session-garbage-collection-php ... en la distribución de Debian/Ubuntu, PHP por defecto desactiva su mecanismo de recolección de basura de sesión. En cambio, ejecuta un trabajo cron cada media hora (ver el script /etc/cron.d/php5) para purgar los archivos de sesión en el directorio/var/lib/php5 /. – renergy

1

para comprobar los valores actuales, este código será útil:

$gc_maxlifetime = ini_get('session.gc_maxlifetime'); 
$gc_probability = ini_get('session.gc_probability'); 
$gc_divisor  = ini_get('session.gc_divisor');