如何在30分钟后过期PHP会话?
我需要保持一个会话30分钟,然后摧毁它。
你应该实现你自己的会话超时。 其他人提到的两个选项( session.gc_maxlifetime和session.cookie_lifetime )都不可靠。 我会解释原因。
第一:
的session.gc_maxlifetime
session.gc_maxlifetime指定数据被视为“垃圾”并清理之前的秒数。 垃圾收集发生在会话开始。
但是垃圾收集器仅以session.gc_probability除以session.gc_divisor的概率启动。 并使用这些选项的默认值(分别为1和100),机会只有1%。
那么,您可以简单地调整这些值,以便更频繁地启动垃圾回收器。 但是当垃圾收集器启动时,它会检查每个注册会话的有效性。 这是成本密集型的。
此外,使用PHP的默认session.save_handler文件时,会话数据将存储在session.save_path中指定的path中的文件中。 使用该会话处理程序,会话数据的年龄根据文件的上次修改date计算,而不是上次访问date:
注意:如果您使用默认的基于文件的会话处理程序,则文件系统必须跟踪访问时间(atime)。 Windows的FAT不这样你就不得不拿出另一种方式来处理垃圾收集你的会议,如果你坚持一个FAT文件系统或任何其他文件系统的时间跟踪不可用。 自PHP 4.2.3以来,它使用mtime(修改date)而不是atime。 所以,你不会遇到没有时间跟踪的文件系统的问题。
因此会话数据文件被删除,而会话本身仍被视为有效,因为会话数据最近没有更新。
第二:
session.cookie_lifetime
session.cookie_lifetime以秒为单位指定发送给浏览器的cookie的生命周期。 […]
恩,那就对了。 这只会影响cookie的生命周期,会话本身可能仍然有效。 但是服务器的任务是使会话无效,而不是客户端。 所以这没有任何帮助。 事实上,将session.cookie_lifetime设置为0
会使会话的cookie成为一个真正的会话cookie ,它只有在浏览器closures之前才有效。
结论/最佳解决scheme:
最好的解决scheme是实现您自己的会话超时。 使用表示最后一次活动(即请求)的时间的简单时间戳,并用每个请求更新它:
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
使用每个请求更新会话数据还会更改会话文件的修改date,以便会话不会被垃圾收集器过早删除。
您还可以使用附加时间戳记定期重新生成会话ID以避免会话攻击,如会话注视 :
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 }
笔记:
-
session.gc_maxlifetime
应至less等于此自定义到期处理程序的生命周期(本例中为1800); - 如果您想在活动 30分钟后而不是30分钟后过期,则还需要使用
setcookie
,过期time()+60*30
才能保持会话cookie处于活动状态。
PHP会话在30分钟内到期的简单方法。
注意:如果你想改变时间,只需要改变你想要的时间,不要改变* 60:这会给出分钟。
在几分钟内:(30 * 60)
天数:(n * 24 * 60 * 60)n =没有天数
的login.php
<?php session_start(); ?> <html> <form name="form1" method="post"> <table> <tr> <td>Username</td> <td><input type="text" name="text1"></td> </tr> <tr> <td>Password</td> <td><input type="password" name="pwd"></td> </tr> <tr> <td><input type="submit" value="SignIn" name="submit1"></td> </tr> </table> </form> </html> <?php if ($_POST['submit1']) { $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!"; } } ?>
HomePage.php
<?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 } } ?>
LogOut.php
<?php session_start(); session_destroy(); header('Location: http://localhost/somefolder/login.php'); ?>
这是否在设定的时间之后logging用户? 在注册时设置会话创build时间(或到期时间),然后检查每个页面加载可以处理的时间。
例如:
$_SESSION['example'] = array('foo' => 'bar', 'registered' => time()); // later if ((time() - $_SESSION['example']['registered']) > (60 * 30)) { unset($_SESSION['example']); }
编辑:我有一种感觉,你的意思是别的。
您可以使用session.gc_maxlifetime
ini设置在一定的使用期限后取消会话:
编辑: ini_set('session.gc_maxlifetime',60 * 30);
这篇文章展示了几种控制会话超时的方法: http : //bytes.com/topic/php/insights/889606-setting-timeout-php-sessions
恕我直言第二个选项是一个不错的解决scheme:
<?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); } }
那么我明白上面的答案是正确的,但他们在应用程序级别,为什么我们不使用.htaccess
文件来设置过期时间?
<IfModule mod_php5.c> #Session timeout php_value session.cookie_lifetime 1800 php_value session.gc_maxlifetime 1800 </IfModule>
if (isSet($_SESSION['started'])){ if((mktime() - $_SESSION['started'] - 60*30) > 0){ //Logout, destroy session, etc. } } else { $_SESSION['started'] = mktime(); }
使用session_set_cookie_params
来做到这一点。
在session_start()
调用之前需要调用这个函数。
尝试这个:
$lifetime = strtotime('+30 minutes', 0); session_set_cookie_params($lifetime); session_start();
更多在: http : //php.net/manual/function.session-set-cookie-params.php
用下面这样的函数实际上很简单。 它使用数据库表名'会话'字段'id'和'时间'。
每当用户再次访问您的站点或服务时,您应该调用此函数来检查其返回值是否为TRUE。 如果它是FALSE用户已经过期,会话将被销毁(注意:这个函数使用数据库类来连接和查询数据库,当然你也可以在你的函数或类似的东西):
function session_timeout_ok() { global $db; $timeout = SESSION_TIMEOUT; //const, eg 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; }
在会话中存储时间戳
<?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"); } ?>
现在,检查时间戳是否在允许的时间窗内(1800秒是30分钟)
<?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 } ?>
请在每个页面加载的包含文件中使用以下代码块。
$expiry = 1800 ;//session expiry required after 30 mins if (isset($_SESSION['LAST']) && (time() - $_SESSION['LAST'] > $expiry)) { session_unset(); session_destroy(); } $_SESSION['LAST'] = time();