2010-08-06 19 views
16

guión El PHP es como sigue:PHP - ini_set ('session.gc_maxlifetime', 5) - ¿Por qué no termina la sesión?

<?php // continue.php 
ini_set('session.gc_maxlifetime', 5); 
session_start(); 
echo ini_get('session.gc_maxlifetime'); 
// wait for 7 seconds 
usleep(7000000); 
if (isset($_SESSION['username'])) 
{ 
    $username = $_SESSION['username']; 
    $password = $_SESSION['password']; 
    $forename = $_SESSION['forename']; 
    $surname = $_SESSION['surname']; 

    echo "Welcome back $forename.<br /> 
      Your full name is $forename $surname.<br /> 
      Your username is '$username' 
      and your password is '$password'."; 
} 
else echo "Please <a href=authenticate2.php>click here</a> to log in."; 

?> 

Basado en el tiempo de espera (es decir, 5 segundos), la secuencia de comandos no se debe imprimir nada. Sin embargo, todavía recibir el siguiente mensaje

5Welcome back Bill. Your full name is Bill Smith. Your username is 'bsmith' and your password is 'mysecret'. 

Parece que la línea de ini_set ('session.gc_maxlifetime', 5) no funciona como debería ser. Estoy usando Windows XP + XAMMP.

¿Me puede decir cómo hacerlo funcionar?

Gracias

Respuesta

4

leer el (el énfasis es mío) manual:

session.gc_maxlifetime especifica el número de segundos que se verá de datos como 'basura' y potencialmente limpiado. La recolección de basura puede ocurrir durante el inicio de la sesión (según session.gc_probability y session.gc_divisor).

En la misma página:

session.gc_divisor acopla con session.gc_probability define la probabilidad de que el proceso de GC (recolección de basura) se inicia en cada inicialización de sesión. La probabilidad se calcula utilizando gc_probability/gc_divisor, p. 1/100 significa que hay un 1% de posibilidades de que el proceso de GC comience en cada solicitud. session.gc_divisor se predetermina a 100.

Ahora haga los cálculos y vea que no es muy probable que se llame al GC en cada solicitud.

Debe almacenar en la sesión una variable que ahorra el tiempo de la última actividad del usuario y usarla en lugar de la sesión lógicamente "activa". No confíes en la recolección de basura.

+0

Creo que el punto aquí es que la sesión todavía está activa y, por lo tanto, probablemente no debería estar sujeta a la recolección de basura en ningún caso. No obstante, no estoy seguro. –

+0

@Pekka El punto es que la recolección de basura es inútil aquí porque 1) solo se llamará con una pequeña probabilidad y 2) solo se llama en 'session_start'. – Artefacto

+0

de acuerdo. Además, la recolección de basura es aún más inútil porque la sesión en la que estamos todavía está activa (y algún controlador interno presumiblemente bloqueado). ¿Correcto? –

1

No creo que así sea como se supone que gc_maxlifetime funciona. El manual dice

session.gc_maxlifetime especifica el número de segundos que se verá de datos como 'basura' y potencialmente limpiado.

(el énfasis es mío)

en su caso, la sesión está todavía activo. Por lo tanto, no creo que esté sujeto a la recolección de basura.

Puede intentar hacer un session_write_close() antes de la suspensión(). Eso podría aumentar la probabilidad de que el recolector de basura.

+0

Él tenía la misma idea en el énfasis: p – Artefacto

+0

@Artefacto sí, ¡qué gracioso! :) –

+0

Hola a todos, Agregué las siguientes líneas, pero todavía no funciona. ini_set ('session.gc_maxlifetime', 5); ini_set ('gc_probability', 100); ini_set ('gc_divisor', 100); Lo que quiero hacer es forzar el vencimiento automático de la sesión después de 5 segundos. Si este método no funciona, ¿cómo hacerlo funcionar? gracias – q0987

9

session.gc_maxlifetime es el número de segundos que la sesión será considerada para la recolección de basura.

sesión.gc_probability y session.gc_divisor luego determinar la probabilidad de que la recolección de basura se ejecutará en cualquier inicialización de sesión

34

Incluso si el recolector de basura se hizo presente y borra el archivo de sesión que abrió/lectura con session_start(), no va a llegar a las entrañas de ese proceso particular de PHP y elimine la matriz de objetos $_SESSION.

Suponiendo que está en el controlador de sesión basado en archivos estándar (que contiene una copia serialize() 'de $_SESSION), esto es lo que sucede.

  1. El archivo de sesión se encuentra en su directorio temporal
  2. Usted session_start(), por ello PHP para abrir/cerrar el archivo, leer su contenido, deserializar los datos, y de paso, posiblemente actualizar "utilizado por última vez" marca de tiempo del archivo de sesión (atime en cajas Unix).
  3. Si las estrellas y la luna están alineadas correctamente con Neptune ascendente en la quinta casa, el recolector de basura de la sesión MAY enciende y elimina los archivos de sesión anteriores.
  4. El recolector de basura iterará felizmente en el directorio de sesión y eliminará cualquier archivo que sea anterior al max_liftime, PERO NO ELIMINARÁ NINGÚN ARCHIVO ACTUALMENTE ABIERTO/EN USO. Como no ha cerrado() su sesión, el archivo de su sesión todavía está en uso, por lo que no se eliminará.

Ahora, si se hizo algo como esto:

ini_set(...); // set GC probability to max, short session lifetime, etc... 

session_start(); // populate $_SESSION 
session_write_close(); // dump $_SESSION out to file, close file, release lock. 

sleep(7); // Sleep for 7 seconds; 

session_start(); // re-populate $_SESSION; 

Ahora que sólo podría terminar con un fresco en blanco $ _SESSION, SI el recolector de basura decide patear Sin embargo, a menos que usted. hacer ese segundo session_start(), los datos antiguos $ _SESSION de la llamada start() anterior TODAVÍA ESTARÁN PRESENTES. Es posible que el archivo de la sesión se haya destruido, pero el recolector de elementos no utilizados no tocará lo que está presente en la memoria del script mientras se ejecuta.

+2

¿Estás seguro de que el recolector de basura no se ejecuta * antes * 'session_start()' llena la matriz '$ _SESSION'? ¿Tienes una URL que confirme esto? –

+3

+1 para # 3 y para 'session_write_close()' ¡buena idea! –

Cuestiones relacionadas