Ich muss eine Sitzung 30 Minuten lang am Leben halten und sie dann zerstören.
Ich muss eine Sitzung 30 Minuten lang am Leben halten und sie dann zerstören.
Antworten:
Sie sollten ein eigenes Sitzungszeitlimit implementieren. Beide von anderen genannten Optionen ( session.gc_maxlifetime und session.cookie_lifetime ) sind nicht zuverlässig. Ich werde die Gründe dafür erklären.
Zuerst:
session.gc_maxlifetime
session.gc_maxlifetime gibt die Anzahl der Sekunden an, nach denen Daten als "Müll" angesehen und bereinigt werden. Die Speicherbereinigung erfolgt während des Sitzungsstarts.
Der Garbage Collector wird jedoch nur mit einer Wahrscheinlichkeit von session.gc_probability geteilt durch session.gc_divisor gestartet . Bei Verwendung der Standardwerte für diese Optionen (1 bzw. 100) liegt die Chance nur bei 1%.
Sie können diese Werte einfach so anpassen, dass der Garbage Collector häufiger gestartet wird. Wenn der Garbage Collector gestartet wird, überprüft er die Gültigkeit für jede registrierte Sitzung. Und das ist kostenintensiv.
Wenn Sie die Standarddateien session.save_handler von PHP verwenden, werden die Sitzungsdaten in Dateien in einem in session.save_path angegebenen Pfad gespeichert . Mit diesem Sitzungshandler wird das Alter der Sitzungsdaten am letzten Änderungsdatum der Datei und nicht am letzten Zugriffsdatum berechnet:
Hinweis: Wenn Sie den standardmäßigen dateibasierten Sitzungshandler verwenden, muss Ihr Dateisystem die Zugriffszeiten (atime) verfolgen. Windows FAT funktioniert nicht, daher müssen Sie sich eine andere Möglichkeit einfallen lassen, um die Speicherbereinigung Ihrer Sitzung zu handhaben, wenn Sie mit einem FAT-Dateisystem oder einem anderen Dateisystem feststecken, für das keine Zeiterfassung verfügbar ist. Seit PHP 4.2.3 wird mtime (Änderungsdatum) anstelle von atime verwendet. Sie haben also keine Probleme mit Dateisystemen, in denen keine Zeiterfassung verfügbar ist.
Daher kann es zusätzlich vorkommen, dass eine Sitzungsdatendatei gelöscht wird, während die Sitzung selbst noch als gültig betrachtet wird, da die Sitzungsdaten kürzlich nicht aktualisiert wurden.
Und zweitens:
session.cookie_lifetime
session.cookie_lifetime gibt die Lebensdauer des Cookies in Sekunden an, das an den Browser gesendet wird. […]
Ja, das ist richtig. Dies wirkt sich nur auf die Lebensdauer der Cookies aus und die Sitzung selbst ist möglicherweise noch gültig. Es ist jedoch die Aufgabe des Servers, eine Sitzung ungültig zu machen, nicht der Client. Das hilft also nichts. In der Tat, mit session.cookie_lifetime zu Satz 0
würde die Cookie - Sitzung eines echtes Session - Cookie , das nur gültig , bis der Browser geschlossen wird.
Fazit / beste Lösung:
Die beste Lösung besteht darin, ein eigenes Sitzungszeitlimit zu implementieren. Verwenden Sie einen einfachen Zeitstempel, der die Zeit der letzten Aktivität (dh Anforderung) angibt, und aktualisieren Sie ihn bei jeder Anforderung:
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
// last request was more than 30 minutes ago
session_unset(); // unset $_SESSION variable for the run-time
session_destroy(); // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp
Durch das Aktualisieren der Sitzungsdaten bei jeder Anforderung wird auch das Änderungsdatum der Sitzungsdatei geändert, sodass die Sitzung vom Garbage Collector nicht vorzeitig entfernt wird.
Sie können auch einen zusätzlichen Zeitstempel verwenden, um die Sitzungs-ID regelmäßig neu zu generieren, um Angriffe auf Sitzungen wie die Sitzungsfixierung zu vermeiden :
if (!isset($_SESSION['CREATED'])) {
$_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > 1800) {
// session started more than 30 minutes ago
session_regenerate_id(true); // change session ID for the current session and invalidate old session ID
$_SESSION['CREATED'] = time(); // update creation time
}
Anmerkungen:
session.gc_maxlifetime
sollte mindestens der Lebensdauer dieses benutzerdefinierten Ablaufbehandlungsprogramms entsprechen (in diesem Beispiel 1800);setcookie
mit einem Ablaufdatum von verwenden time()+60*30
, um das Sitzungscookie aktiv zu halten.$_SESSION['LAST_ACTIVITY']
wie den Ort, an $_SESSION['CREATED']
dem Sie die Zeit der letzten Aktivität des Benutzers speichern, aber aktualisieren Sie diesen Wert bei jeder Anforderung. Wenn der Unterschied zwischen dieser Zeit und der aktuellen Zeit größer als 1800 Sekunden ist, wurde die Sitzung nicht länger als 30 Minuten verwendet.
session_unset
macht das gleiche wie $_SESSION = array()
.
ini_set('session.gc-maxlifetime', 1800)
? Andernfalls könnten Ihre Sitzungsinformationen zerstört werden, während Ihre Sitzung noch gültig sein soll, zumindest wenn die INI-Einstellung die Standardeinstellung von 24 Minuten ist. Oder fehlt mir etwas?
files
verwendet wird. Daher sollte session.gc_maxlifetime mindestens der Lebensdauer dieses benutzerdefinierten Ablaufhandlers entsprechen.
Hinweis: Wenn Sie die Zeit ändern möchten, ändern Sie einfach die 30 mit der gewünschten Zeit und ändern Sie nicht * 60: Dies gibt die Minuten an.
In Minuten: (30 * 60)
In Tagen: (n * 24 * 60 * 60) n = Anzahl der Tage
<?php
session_start();
?>
<html>
<form name="form1" method="post">
<table>
<tr>
<td>Username</td>
<td><input type="text" name="text"></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="pwd"></td>
</tr>
<tr>
<td><input type="submit" value="SignIn" name="submit"></td>
</tr>
</table>
</form>
</html>
<?php
if (isset($_POST['submit'])) {
$v1 = "FirstUser";
$v2 = "MyPassword";
$v3 = $_POST['text'];
$v4 = $_POST['pwd'];
if ($v1 == $v3 && $v2 == $v4) {
$_SESSION['luser'] = $v1;
$_SESSION['start'] = time(); // Taking now logged in time.
// Ending a session in 30 minutes from the starting time.
$_SESSION['expire'] = $_SESSION['start'] + (30 * 60);
header('Location: http://localhost/somefolder/homepage.php');
} else {
echo "Please enter the username or password again!";
}
}
?>
<?php
session_start();
if (!isset($_SESSION['luser'])) {
echo "Please Login again";
echo "<a href='http://localhost/somefolder/login.php'>Click Here to Login</a>";
}
else {
$now = time(); // Checking the time now when home page starts.
if ($now > $_SESSION['expire']) {
session_destroy();
echo "Your session has expired! <a href='http://localhost/somefolder/login.php'>Login here</a>";
}
else { //Starting this else one [else1]
?>
<!-- From here all HTML coding can be done -->
<html>
Welcome
<?php
echo $_SESSION['luser'];
echo "<a href='http://localhost/somefolder/logout.php'>Log out</a>";
?>
</html>
<?php
}
}
?>
<?php
session_start();
session_destroy();
header('Location: http://localhost/somefolder/login.php');
?>
Login.php
Headern NACH dem Inhalt gesendet wird, was schlecht ist.
Soll der Benutzer nach einer festgelegten Zeit abgemeldet werden? Wenn Sie die Erstellungszeit der Sitzung (oder eine Ablaufzeit) festlegen, wenn sie registriert wird, und dann überprüfen, ob bei jedem Laden der Seite dies möglich ist.
Z.B:
$_SESSION['example'] = array('foo' => 'bar', 'registered' => time());
// later
if ((time() - $_SESSION['example']['registered']) > (60 * 30)) {
unset($_SESSION['example']);
}
Edit: Ich habe das Gefühl, du meinst aber etwas anderes.
Sie können Sitzungen nach einer bestimmten Lebensdauer mithilfe der session.gc_maxlifetime
INI-Einstellung verschrotten:
Bearbeiten: ini_set ('session.gc_maxlifetime', 60 * 30);
gc_maxlifetime
oder gc-maxlifetime
. Unterstützt es sowohl Unterstriche als auch Bindestriche?
Dieser Beitrag zeigt verschiedene Möglichkeiten zur Steuerung des Sitzungszeitlimits: http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions
IMHO ist die zweite Option eine schöne Lösung:
<?php
/***
* Starts a session with a specific timeout and a specific GC probability.
* @param int $timeout The number of seconds until it should time out.
* @param int $probability The probablity, in int percentage, that the garbage
* collection routine will be triggered right now.
* @param strint $cookie_domain The domain path for the cookie.
*/
function session_start_timeout($timeout=5, $probability=100, $cookie_domain='/') {
// Set the max lifetime
ini_set("session.gc_maxlifetime", $timeout);
// Set the session cookie to timout
ini_set("session.cookie_lifetime", $timeout);
// Change the save path. Sessions stored in teh same path
// all share the same lifetime; the lowest lifetime will be
// used for all. Therefore, for this to work, the session
// must be stored in a directory where only sessions sharing
// it's lifetime are. Best to just dynamically create on.
$seperator = strstr(strtoupper(substr(PHP_OS, 0, 3)), "WIN") ? "\\" : "/";
$path = ini_get("session.save_path") . $seperator . "session_" . $timeout . "sec";
if(!file_exists($path)) {
if(!mkdir($path, 600)) {
trigger_error("Failed to create session save path directory '$path'. Check permissions.", E_USER_ERROR);
}
}
ini_set("session.save_path", $path);
// Set the chance to trigger the garbage collection.
ini_set("session.gc_probability", $probability);
ini_set("session.gc_divisor", 100); // Should always be 100
// Start the session!
session_start();
// Renew the time left until this session times out.
// If you skip this, the session will time out based
// on the time when it was created, rather than when
// it was last used.
if(isset($_COOKIE[session_name()])) {
setcookie(session_name(), $_COOKIE[session_name()], time() + $timeout, $cookie_domain);
}
}
Nun, ich verstehe, dass die obigen Antworten korrekt sind, aber sie befinden sich auf Anwendungsebene. Warum verwenden wir nicht einfach die .htaccess
Datei, um die Ablaufzeit festzulegen ?
<IfModule mod_php5.c>
#Session timeout
php_value session.cookie_lifetime 1800
php_value session.gc_maxlifetime 1800
</IfModule>
Verwenden Sie dazu die session_set_cookie_params
Funktion.
Ist notwendig, diese Funktion vorher aufzurufen session_start()
Aufruf aufzurufen.
Versuche dies:
$lifetime = strtotime('+30 minutes', 0);
session_set_cookie_params($lifetime);
session_start();
Weitere Informationen finden Sie unter : http://php.net/manual/function.session-set-cookie-params.php
Mit einer Funktion wie der folgenden ist es eigentlich einfach. Es verwendet den Namen der Datenbanktabelle 'Sitzungen' mit den Feldern 'ID' und 'Zeit'.
Jedes Mal, wenn der Benutzer Ihre Site oder Ihren Dienst erneut besucht, sollten Sie diese Funktion aufrufen, um zu überprüfen, ob der Rückgabewert TRUE ist. Wenn es FALSE ist, ist der Benutzer abgelaufen und die Sitzung wird zerstört (Hinweis: Diese Funktion verwendet eine Datenbankklasse, um die Datenbank zu verbinden und abzufragen. Natürlich können Sie dies auch in Ihrer Funktion oder ähnlichem tun):
function session_timeout_ok() {
global $db;
$timeout = SESSION_TIMEOUT; //const, e.g. 6 * 60 for 6 minutes
$ok = false;
$session_id = session_id();
$sql = "SELECT time FROM sessions WHERE session_id = '".$session_id."'";
$rows = $db->query($sql);
if ($rows === false) {
//Timestamp could not be read
$ok = FALSE;
}
else {
//Timestamp was read succesfully
if (count($rows) > 0) {
$zeile = $rows[0];
$time_past = $zeile['time'];
if ( $timeout + $time_past < time() ) {
//Time has expired
session_destroy();
$sql = "DELETE FROM sessions WHERE session_id = '" . $session_id . "'";
$affected = $db -> query($sql);
$ok = FALSE;
}
else {
//Time is okay
$ok = TRUE;
$sql = "UPDATE sessions SET time='" . time() . "' WHERE session_id = '" . $session_id . "'";
$erg = $db -> query($sql);
if ($erg == false) {
//DB error
}
}
}
else {
//Session is new, write it to database table sessions
$sql = "INSERT INTO sessions(session_id,time) VALUES ('".$session_id."','".time()."')";
$res = $db->query($sql);
if ($res === FALSE) {
//Database error
$ok = false;
}
$ok = true;
}
return $ok;
}
return $ok;
}
Speichern Sie einen Zeitstempel in der Sitzung
<?php
$user = $_POST['user_name'];
$pass = $_POST['user_pass'];
require ('db_connection.php');
// Hey, always escape input if necessary!
$result = mysql_query(sprintf("SELECT * FROM accounts WHERE user_Name='%s' AND user_Pass='%s'", mysql_real_escape_string($user), mysql_real_escape_string($pass));
if( mysql_num_rows( $result ) > 0)
{
$array = mysql_fetch_assoc($result);
session_start();
$_SESSION['user_id'] = $user;
$_SESSION['login_time'] = time();
header("Location:loggedin.php");
}
else
{
header("Location:login.php");
}
?>
Überprüfen Sie nun, ob der Zeitstempel innerhalb des zulässigen Zeitfensters liegt (1800 Sekunden sind 30 Minuten).
<?php
session_start();
if( !isset( $_SESSION['user_id'] ) || time() - $_SESSION['login_time'] > 1800)
{
header("Location:login.php");
}
else
{
// uncomment the next line to refresh the session, so it will expire after thirteen minutes of inactivity, and not thirteen minutes after login
//$_SESSION['login_time'] = time();
echo ( "this session is ". $_SESSION['user_id'] );
//show rest of the page and all other content
}
?>
Bitte verwenden Sie den folgenden Codeblock in Ihrer Include-Datei, der auf allen Seiten geladen wird.
$expiry = 1800 ;//session expiry required after 30 mins
if (isset($_SESSION['LAST']) && (time() - $_SESSION['LAST'] > $expiry)) {
session_unset();
session_destroy();
}
$_SESSION['LAST'] = time();
Verwenden Sie diese Klasse für 30 Minuten
class Session{
public static function init(){
ini_set('session.gc_maxlifetime', 1800) ;
session_start();
}
public static function set($key, $val){
$_SESSION[$key] =$val;
}
public static function get($key){
if(isset($_SESSION[$key])){
return $_SESSION[$key];
} else{
return false;
}
}
public static function checkSession(){
self::init();
if(self::get("adminlogin")==false){
self::destroy();
header("Location:login.php");
}
}
public static function checkLogin(){
self::init();
if(self::get("adminlogin")==true){
header("Location:index.php");
}
}
public static function destroy(){
session_destroy();
header("Location:login.php");
}
}
Zeitstempel verwenden ...
<?php
if (!isset($_SESSION)) {
$session = session_start();
}
if ($session && !isset($_SESSION['login_time'])) {
if ($session == 1) {
$_SESSION['login_time']=time();
echo "Login :".$_SESSION['login_time'];
echo "<br>";
$_SESSION['idle_time']=$_SESSION['login_time']+20;
echo "Session Idle :".$_SESSION['idle_time'];
echo "<br>";
} else{
$_SESSION['login_time']="";
}
} else {
if (time()>$_SESSION['idle_time']){
echo "Session Idle :".$_SESSION['idle_time'];
echo "<br>";
echo "Current :".time();
echo "<br>";
echo "Session Time Out";
session_destroy();
session_unset();
} else {
echo "Logged In<br>";
}
}
?>
Ich habe 20 Sekunden verwendet, um die Sitzung mit dem Zeitstempel abzulaufen .
Wenn Sie 30 Minuten benötigen, fügen Sie 1800 hinzu (30 Minuten in Sekunden) ...
Alternativ können Sie auch eine Datenbank verwenden. Ich benutze dazu eine DB-Funktion, die ich chk_lgn aufrufe.
Überprüfen Sie die Anmeldeprüfungen, um festzustellen, ob sie angemeldet sind oder nicht. Dabei wird der Datums- und Zeitstempel der Prüfung als zuletzt aktiv in der Datenbankzeile / -spalte des Benutzers festgelegt.
Dort überprüfe ich auch die Zeit. Dies funktioniert für mich im Moment, da ich diese Funktion für jede Seite verwende.
PS Niemand, den ich gesehen hatte, hatte eine reine DB-Lösung vorgeschlagen.
Wie PHP mit Sitzungen umgeht, ist für Anfänger ziemlich verwirrend. Dies kann ihnen helfen, indem sie einen Überblick über die Funktionsweise von Sitzungen geben: Funktionsweise von Sitzungen (benutzerdefinierte Sitzungshandler)
Speichern Sie einfach die aktuelle Zeit und zerstören Sie die aktuelle Sitzung, wenn sie beim Vergleich 30 Minuten überschreitet.