Heim  >  Artikel  >  php教程  >  Problem mit der Gültigkeit der PHP-Sitzung

Problem mit der Gültigkeit der PHP-Sitzung

高洛峰
高洛峰Original
2016-12-24 09:15:591468Durchsuche

Eine bekannte effektive Methode besteht darin, session_set_save_handler zu verwenden, um die gesamte Sitzungsverwaltungsarbeit zu übernehmen. Im Allgemeinen werden die Sitzungsinformationen in der Datenbank gespeichert, sodass alle abgelaufenen Sitzungen über SQL-Anweisungen gelöscht und die Gültigkeitsdauer der Sitzung überprüft werden können genau kontrolliert. Dies ist auch eine häufig verwendete Methode für große Websites, die auf PHP basieren. Für gewöhnliche kleine Websites scheint es jedoch nicht nötig zu sein, so hart zu arbeiten.
Die Lebensdauer einer allgemeinen Sitzung ist jedoch begrenzt. Wenn der Benutzer den Browser schließt, können die Sitzungsvariablen nicht gespeichert werden! Wie können wir also die dauerhafte Lebensdauer von Session erreichen?
Wie wir alle wissen, wird die Sitzung auf der Serverseite gespeichert, basierend auf der vom Client bereitgestellten Sitzungs-ID, und dann wird die Datei gelesen, um den Wert der Variablen zu erhalten Das Cookie des Clients oder der Query_String des Http1.1-Protokolls (d. h. (der Teil nach dem „?“ in der aufgerufenen URL) wird an den Server übertragen, und dann liest der Server das Verzeichnis der Sitzung...
Um die dauerhafte Lebensdauer der Sitzung zu realisieren, müssen Sie zunächst die relevanten Einstellungen der Sitzung in php.ini verstehen (öffnen Sie die php.ini-Datei im Abschnitt „[Sitzung]“):
1. Der Standardwert ist „1“, was bedeutet, dass die SessionID von Cookie übergeben wird, andernfalls wird sie von Query_String übergeben.
2: Dies ist der in SessionID gespeicherte Variablenname, der von Cookie oder übergeben werden kann Query_String. Der Standardwert ist „PHPSESSID“;
3. Dies stellt die Zeit dar, die die SessionID im Client-Cookie gespeichert wird schließt es... Aus diesem Grund kann die Sitzung nicht dauerhaft genutzt werden!
4. session.gc_maxlifetime: Dies ist die Zeit, die Sitzungsdaten auf der Serverseite gespeichert werden. Wenn diese Zeit überschritten wird, werden die Sitzungsdaten automatisch gelöscht!
Es gibt noch viele weitere Einstellungen, aber diese beziehen sich auf diesen Artikel. Beginnen wir mit den Prinzipien und Schritten der Verwendung einer permanenten Sitzung.
Wie bereits erwähnt, liest der Server Sitzungsdaten über SessionID, aber im Allgemeinen ist die vom Browser gesendete SessionID nach dem Schließen des Browsers verschwunden, sodass wir die SessionID nur manuell festlegen und speichern müssen, nein ...
Wenn Sie über die Betriebsberechtigung des Servers verfügen, ist die Einstellung sehr einfach. Sie müssen lediglich die folgenden Schritte ausführen:
1. Setzen Sie „session.use_cookies“ auf 1 und aktivieren Sie „Cookie zum Speichern der SessionID“. aber der Standardwert ist 1. , im Allgemeinen keine Änderung erforderlich;
3. Stellen Sie „session.gc_maxlifetime“ ein. Dies ist die gleiche Zeit wie „session.cookie_lifetime“.
In der PHP-Dokumentation ist klar angegeben, dass der Parameter zum Festlegen der Sitzungsgültigkeitsdauer session.gc_maxlifetime ist. Dieser Parameter kann in der Datei php.ini oder über die Funktion ini_set() geändert werden. Das Problem besteht darin, dass die Änderung dieses Parameters nach vielen Tests grundsätzlich keine Auswirkung hat und die Sitzungsgültigkeitsdauer immer noch den Standardwert von 24 Minuten beibehält.
Aufgrund des Arbeitsmechanismus von PHP verfügt es nicht über einen Daemon-Thread, um Sitzungsinformationen regelmäßig zu scannen und festzustellen, ob sie ungültig sind. Wenn eine gültige Anfrage auftritt, entscheidet PHP basierend auf dem Wert der globalen Variablen session.gc_probability/session.gc_divisor (die auch über die Funktion php.ini oder ini_set() geändert werden kann) ob ein GC (Garbage Collector) gestartet wird. . Standardmäßig ist session.gc_probability = 1, session.gc_divisor = 100, was bedeutet, dass die Wahrscheinlichkeit, dass GC gestartet wird, bei 1 % liegt.
Die Aufgabe von GC besteht darin, alle Sitzungsinformationen zu scannen, die letzte Änderungszeit (Änderungsdatum) der Sitzung von der aktuellen Zeit zu subtrahieren und sie mit dem Parameter session.gc_maxlifetime zu vergleichen. Wenn die Überlebenszeit gc_maxlifetime überschritten hat, wird gelöscht die Sitzung.
Bisher funktioniert alles gut. Warum wird gc_maxlifetime ungültig?
Standardmäßig werden Sitzungsinformationen in Form von Textdateien im temporären Dateiverzeichnis des Systems gespeichert. Unter Linux ist dieser Pfad normalerweise tmp und unter Windows normalerweise C:WindowsTemp. Wenn mehrere PHP-Anwendungen auf dem Server vorhanden sind, speichern diese ihre Sitzungsdateien im selben Verzeichnis. Ebenso starten diese PHP-Anwendungen mit einer bestimmten Wahrscheinlichkeit auch GC und scannen alle Sitzungsdateien.
Das Problem besteht darin, dass GC, wenn es funktioniert, nicht zwischen Sitzungen auf verschiedenen Sites unterscheidet. Beispielsweise ist gc_maxlifetime für Standort A auf 2 Stunden und gc_maxlifetime für Standort B auf den Standardwert von 24 Minuten festgelegt. Wenn der GC von Site B startet, scannt er das öffentliche temporäre Dateiverzeichnis und löscht alle Sitzungsdateien, die älter als 24 Minuten sind, unabhängig davon, ob sie von Site A oder B stammen. Auf diese Weise ist die gc_maxlifetime-Einstellung von Site A nutzlos.
Sobald Sie das Problem gefunden haben, ist es einfach, es zu lösen. Ändern Sie den Parameter session.save_path oder verwenden Sie die Funktion session_save_path(), um das Verzeichnis, in dem die Sitzung gespeichert wird, auf ein dediziertes Verzeichnis zu verweisen. Der Parameter gc_maxlifetime funktioniert normal.
Genau genommen ist das ein Fehler in PHP?
Ein weiteres Problem besteht darin, dass gc_maxlifetime nur die kürzeste Überlebenszeit der Sitzung garantieren kann und nicht gespeichert werden kann. Nach dieser Zeit werden die Sitzungsinformationen sofort gelöscht. Da GC auf Wahrscheinlichkeitsbasis gestartet wird und möglicherweise über einen längeren Zeitraum nicht gestartet wird, ist eine große Anzahl von Sitzungen auch nach Überschreiten von gc_maxlifetime noch gültig. Eine Möglichkeit, dieses Problem zu lösen, besteht darin, die Wahrscheinlichkeit von session.gc_probability/session.gc_divisor auf 100 % zu erhöhen. Dieses Problem wird zwar vollständig gelöst, hat jedoch offensichtlich schwerwiegende Auswirkungen auf die Leistung. Eine andere Methode besteht darin, die Lebensdauer der aktuellen Sitzung in Ihrem Code zu bestimmen. Wenn sie gc_maxlifetime überschreitet, löschen Sie die aktuelle Sitzung.
Wenn Sie jedoch nicht über die Berechtigung zum Betreiben des Servers verfügen, ist dies problematischer. Sie müssen die SessionID über das PHP-Programm neu schreiben, um eine dauerhafte Speicherung der Sitzungsdaten zu erreichen. Schauen Sie im Funktionshandbuch von php.net nach und Sie können die Funktion „session_id“ sehen: Wenn keine Parameter gesetzt sind, wird die aktuelle SessionID zurückgegeben. Wenn die Parameter gesetzt sind, wird die aktuelle SessionID auf den angegebenen Wert gesetzt...
Solange Sie ein permanentes Cookie verwenden und die Funktion „session_id“ hinzufügen, können Sie permanente Sitzungsdaten speichern!
Aber der Einfachheit halber müssen wir den vom Server festgelegten „session.name“ kennen, aber die meisten Benutzer haben keine Berechtigung, die php.ini-Einstellungen des Servers anzuzeigen. PHP bietet jedoch eine sehr gute Funktion „phpinfo“. ", mit dem fast alle PHP-Informationen angezeigt werden können!
--------------------------------- --- -------------------------------------
b2386ffb911b14667cb8f0f91ea547a7PHP-bezogene Informationen displayb25a9407cfe693f10872c2a72988c045 -------------------------------------------------- -- --
Öffnen Sie den Editor, geben Sie den obigen Code ein und führen Sie dann das Programm im Browser aus. Sie sehen PHP-bezogene Informationen (wie in Abbildung 1 dargestellt). Es gibt einen Parameter „session.name“, bei dem es sich um den Server „session.name“ handelt, den wir benötigen, normalerweise „phpsessid“.
Nachdem wir den Namen der SessionID notiert haben, können wir eine dauerhafte Speicherung der Sitzungsdaten erreichen!

Postscript:
session_start(); 
ini_set('session.save_path','/tmp/'); 
//6个钟头 
ini_set('session.gc_maxlifetime',21600); 
//保存一天 
$lifeTime = 24 * 3600; 
setcookie(session_name(), session_id(), time() + $lifeTime, "/");
Tatsächlich ist eine echte dauerhafte Speicherung nicht möglich, da die Cookie-Speicherzeit begrenzt ist und der Serverplatz ebenfalls begrenzt ist ... Aber für einige Websites, die gespeichert werden müssen Für eine lange Zeit reicht die obige Methode aus!

Fügen Sie die Sitzung in MySQL ein. Beispiel:
Erstellen Sie eine Tabelle in der Datenbank: session (sesskey varchar32, expiry int11, value longtext)
Code:
Die Datenbank wurde verbunden, bevor der Code ausgeführt wird.

Ich verstehe immer noch nicht, woher die Öffnungs- und Schreibparameter kommen.

Zwei häufig verwendete Funktionen zum Ändern der php.ini-Konfiguration:
define('STORE_SESSIONS','mysql'); 

if (STORE_SESSIONS == 'mysql') { 
if (!$SESS_LIFE = get_cfg_var('session.gc_maxlifetime')) { 
$SESS_LIFE = 1440; 
} 

function _sess_open($save_path, $session_name) { 

// 如果没有连接数据库,可以在此执行mysql_pconnect,mysql_select_db 
return true; 
} 

function _sess_close() { 
return true; 
} 

function _sess_read($key) { 
$value_query = mysql_query("select value from sessions where sesskey = '" .addslashes($key) . "' and expiry > '" . time() . "'"); 
$value = mysql_fetch_array($value_query); 

if (isset($value['value'])) { 
return $value['value']; 
} 

return false; 
} 

function _sess_write($key, $val) { 
global $SESS_LIFE; 

$expiry = time() + $SESS_LIFE; 
$value = $val; 

$check_query = mysql_query("select count(*) as total from sessions where sesskey = '" . addslashes($key) . "'"); 
$check = mysql_fetch_array($check_query); 

if ($check['total'] > 0) { 
return mysql_query("update sessions set expiry = '" . addslashes($expiry) . "', value = '" . addslashes($value) . "' where sesskey = '" . addslashes($key) . "'"); 
} else { 
return mysql_query("insert into sessions values ('" . addslashes($key) . "', '" . addslashes($expiry) . "', '" . addslashes($value) . "')"); 
} 
} 

function _sess_destroy($key) { 
return mysql_query("delete from sessions where sesskey = '" . addslashes($key) . "'"); 
} 

function _sess_gc($maxlifetime) { 
mysql_query("delete from sessions where expiry < &#39;" . time() . "&#39;"); 

return true; 
} 

session_set_save_handler(&#39;_sess_open&#39;, &#39;_sess_close&#39;, &#39;_sess_read&#39;, &#39;_sess_write&#39;, &#39;_sess_destroy&#39;, &#39;_sess_gc&#39;); 
} 

danoo_session_name( &#39;dtvSid&#39; ); 
danoo_session_save_path(SESSION_WRITE_DIRECTORY);
get_cfg_var('session.gc_maxlifetime'): Rufen Sie den Wert von session.gc_maxlifetime ab

ini_set('session.cookie_lifetime','0' ) : Setzen Sie den Wert von session.cookie_lifetime auf 0.

Weitere Artikel zu Problemen mit der Gültigkeit von PHP-Sitzungen finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn