2009-08-06 12 views
33

Was ist der tatsächliche Unterschied zwischen session.gc_maxlifetime und session_cache_expire()?Session Timeouts in PHP: Best Practices

Angenommen, ich möchte, dass die Benutzersitzung nach 15 Minuten Nichtaktivität ungültig ist (und nicht 15 nach dem ersten Öffnen). Welcher von diesen wird mir dort helfen?

Ich weiß auch, dass ich session_set_cookie_params() tun kann, die den Cookie des Benutzers in einer gewissen Zeit ablaufen lassen kann. Der Ablauf des Cookies und die tatsächliche Sitzung, die auf der Serverseite abläuft, sind jedoch nicht identisch. löscht das auch die Sitzung, wenn der Cookie abgelaufen ist?

Eine andere Lösung, die ich obwohl haben, ist einfach $_SESSION['last_time'] = time() auf jede Anfrage, und die Sitzung auf die aktuelle Zeit zu vergleichen, die auf dieser Grundlage Sitzung zu löschen. Ich hatte gehofft, dass es einen "eingebauten" Mechanismus für das Handling gab.

Danke.

+0

Wie ich auf diese Frage mich nach einigen Recherchen stolperte, kann man eine sehr ausführliche Antwort auf dieses Problem auf haben [diese Stackoverflow Frage] (http://StackOverflow.com/a/1270960/474526), ​​insbesondere, warum weder die Aktualisierung von "session.gc_maxlifetime" noch von "session.cookie_lifetime" zuverlässige Ansätze sind. –

Antwort

39

Jedes Mal, wenn session_start aufgerufen wird, wird der Zeitstempel der Sitzungsdateien (sofern vorhanden) aktualisiert, der verwendet wird, um zu berechnen, ob session.gc_maxlifetime überschritten wurde.

Noch wichtiger ist, dass Sie nicht darauf warten können, dass eine Sitzung abläuft, nachdem die session.gc_maxlifetime-Zeit überschritten wurde.

PHP führt Garbage Collection für abgelaufene Sitzungen aus, nachdem die aktuelle Sitzung geladen wurde, und berechnet mithilfe von session.gc_probability und session.gc_divisor die Wahrscheinlichkeit, dass die Garbage Collection ausgeführt wird. Standardmäßig ist es eine 1% Wahrscheinlichkeit.

Bei einer geringen Anzahl von Besuchern besteht die Wahrscheinlichkeit, dass ein inaktiver Benutzer auf eine Sitzung zugreifen kann, die abgelaufen und gelöscht sein sollte. Wenn dies für Sie wichtig ist, müssen Sie einen Zeitstempel in der Sitzung speichern und berechnen, wie der Benutzer protokolliert wurde.

Dieses Beispiel ersetzt session_start und erzwingt einen Timeout:

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 basiert auf der letzten Änderung einer Sitzungsdatei. Jedes Mal, wenn eine Sitzungsdatei geändert wird oder ein session_start() auf einer separaten Seite aufgerufen wird, beginnt der Countdown für gc_maxlifetime erneut und der Benutzer bleibt "angemeldet". Dies ist der Wert, nach dem Sie suchen. Sie können dies durch ini_set() in der PHP-Dateien ändern oder php.ini bearbeiten, wenn Sie Zugriff darauf haben

session_cache_expire() steuert nur die HTTP-Header "Expires". Dieser Header steuert, wie lange der Inhalt der heruntergeladenen Seite im Browser-Cache des Benutzers verbleibt.

49

ich einige Zeit damit verbracht mich für eine gute Antwort darauf, wie die php.ini-Server-Einstellungen vornehmen Sitzungen ablaufen. Ich habe eine Menge Informationen gefunden, aber es hat eine Weile gedauert, bis ich herausgefunden habe, warum die Einstellungen so funktionieren, wie sie es tun. Wenn Sie wie ich sind, könnte dies hilfreich für Sie sein:

Sitzungen sind als Cookies (Dateien auf dem Client-PC) oder Server-Seite als Dateien auf dem Server gespeichert. Beide Methoden haben Vor- und Nachteile.

Für die auf dem Server gespeicherten Sitzungen werden drei Variablen verwendet.

session.gc_probability session.gc_divisor session.gc_maxlifetime

(session.gc_probability/session.gc_divisor) erzeugt, um die Wahrscheinlichkeit, dass die Speicherbereinigungsroutine ausgeführt wird. Wenn der Garbage Collector ausgeführt wird, sucht er nach Sitzungsdateien, auf die mindestens für session.gc_maxlifetime nicht zugegriffen worden ist, und löscht sie.

Das ist alles ziemlich gut in Forum-Beiträgen (! Dies eine besonders) erklärt - Aber die folgenden Fragen kommen auf:

1.) Wie die Wahrscheinlichkeit angewandt wird? Wann würfelt der Server?

A: Der Server würfelt jedes Mal, wenn session_start() während einer aktiven Sitzung auf dem Server aufgerufen wird. Dies bedeutet also, Sie den Müll Kollektorlauf für jeden 100-mal etwa einmal sehen sollen, dass session_start() wird aufgerufen, wenn Sie den Standard von session.gc_probability haben = 1 und session.gc_divisor = 100

2.) Was passiert auf Servern mit geringem Volumen?

A: Wenn session_start() aufgerufen wird, aktualisiert FIRST FIRST die Sitzung und stellt Ihnen die -Sitzungswerte zur Verfügung. Dies aktualisiert die Zeit in Ihrer Sitzungsdatei auf dem Server . Dann würfelt es und wenn es gewinnt (1 von 100 Chancen) ruft es den Müllsammler an. Der Garbage Collector überprüft dann alle Sitzungs-ID-Dateien und erkennt, ob Dateien vorhanden sind, die zum Löschen berechtigt sind.

Dies bedeutet, dass wenn Sie die einzige Person auf dem Server sind, wird Ihre Sitzung nie inaktiv und es wird so aussehen, als ob die Änderung der Einstellungen keine Wirkung haben. Angenommen, Sie ändern session.gc_maxlifetime auf 10 und session.gc_probability auf 100. Dies bedeutet, dass eine 100% ige Chance besteht, dass der Garbage Collector ausgeführt wird und alle Sitzungsdateien löscht, auf die in den letzten 10 Sekunden nicht zugegriffen wurde .

Wenn Sie die einzige Person auf dem Server sind, wird Ihre Sitzung nicht gelöscht. Sie benötigen mindestens 1 andere aktive Sitzung läuft für Ihre inaktiv zu werden.

Also im Grunde auf einem niedrigen Volumen-Server oder auf einem niedrigen Volumen Zeit - es könnte viel länger als session.gc_maxlifetime dauern, bis der Garbage Collector tatsächlich läuft und die Sitzungen tatsächlich gelöscht. Und ohne zu wissen, wie das funktioniert, mag es Ihnen völlig zufällig erscheinen.

3.) Warum verwenden sie die Wahrscheinlichkeit?

A: Leistung. Auf einem Server mit höherem Volumen möchten Sie nicht, dass der Garbage Collector bei jeder Anforderung von session_start() ausgeführt wird. Es wird unnötig den Server verlangsamen. Abhängig von Ihrem Server-Volume sollten Sie daher die Anzahl erhöhen oder die Wahrscheinlichkeit verringern, dass der Garbage Collector ausgeführt wird.

Ich hoffe, dass dies die Dinge für Sie zusammenhält. Wenn Sie wie ich sind und Sie versuchten Sitzung.gc_maxlifetime und es schien nicht zu funktionieren (weil Sie es auf einem Entwicklungsserver ausprobiert, um niemanden zu stören), dann hat dieser Beitrag hoffentlich Sie einige Kopf kratzen gerettet.

Viel Glück!

+3

Sehr informative Antwort! Sollte in den offiziellen PHP-Dokumenten sein. Vielen Dank! –

+0

Sehr klare Antwort ... aber ich möchte nur darauf hinweisen, dass selbst wenn Sie die standardmäßigen dateibasierten Sitzungen von PHP verwenden, ein Cookie immer noch an den Browser des Benutzers gesendet wird. Dies ist ein Sitzungscookie (diese laufen normalerweise ab, wenn sie die Registerkarte/das Fenster schließen) und enthalten einfach ihre Sitzungskennung. So Sitzung "Probleme" möglicherweise nicht auf Servereinstellungen beschränkt. Wenn der Browser des Nutzers diesen Cookie über das Schließen des Tabs/Fensters hinaus "speichert", könnten Sitzungen verloren gehen, die er sonst behalten würde. Gleichermaßen könnte Ihr Durcheinander mit den Einstellungen dieses Cookies die Fähigkeit beeinträchtigen, eine Sitzung am Leben zu erhalten. – simonhamp

+0

von http://www.appnovation.com/blog/session-garbage-collection-php ... in der Debian/Ubuntu-Distribution deaktiviert PHP standardmäßig seinen Session-Garbage-Collection-Mechanismus. Stattdessen wird alle halbe Stunde ein Cron-Job ausgeführt (siehe Skript /etc/cron.d/php5), um Sitzungsdateien im Verzeichnis/var/lib/php5/zu löschen. – renergy

1

die aktuellen Werte zu überprüfen, dieser Code hilfreich sein:

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