我需要让会话保持30分钟,然后将其销毁。
答案 0 :(得分:1590)
您应该实现自己的会话超时。其他人(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中指定的路径中的文件中。使用该会话处理程序,会话数据的年龄是根据文件的上次修改日期计算的,而不是上次访问日期:
注意:如果您使用默认的基于文件的会话处理程序,则您的文件系统必须跟踪访问时间(atime)。如果您遇到FAT文件系统或任何其他无法进行atime跟踪的文件系统,那么Windows FAT不会如此,您将不得不想出另一种方法来处理垃圾收集会话。从PHP 4.2.3开始,它使用了mtime(修改日期)而不是atime。因此,对于没有时间跟踪的文件系统,您不会遇到问题。
因此,当会话本身仍然被认为是有效的时,会删除会话数据文件,因为最近没有更新会话数据。
第二名:
<强> session.cookie_lifetime 强>
session.cookie_lifetime 指定发送到浏览器的cookie的生命周期(以秒为单位)。 [...]
是的,没错。这仅影响cookie生存期,会话本身可能仍然有效。但是服务器的任务是使会话无效,而不是客户端。所以这对任何事都没有帮助。事实上,将 session.cookie_lifetime 设置为0
会使会话的cookie成为真正的session cookie,只有在浏览器关闭之前才有效。
结论/最佳解决方案:
最佳解决方案是实现您自己的会话超时。使用表示最后一次活动(即请求)的时间的简单时间戳,并在每次请求时更新它:
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
每次请求更新会话数据也会更改会话文件的修改日期,以便垃圾收集器不会过早删除会话。
您还可以使用额外的时间戳来定期重新生成会话ID,以避免对session fixation等会话的攻击:
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
应该至少等于此自定义到期处理程序的生命周期(本例中为1800); setcookie
过期time()+60*30
以使会话cookie保持活动状态。答案 1 :(得分:125)
注意:如果你想改变时间,只需用你想要的时间改变30,不要改变* 60:这将给出分钟。
分钟:(30 * 60)
在几天内:(n * 24 * 60 * 60)n =没有天数
<?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');
?>
答案 2 :(得分:38)
这是在一段时间后将用户注销吗?在注册时设置会话创建时间(或到期时间),然后检查每个页面上的负载是否可以处理。
E.g:
$_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);
答案 3 :(得分:21)
这篇文章展示了控制会话超时的几种方法:http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions
恕我直言,第二个选择是一个很好的解决方案:
<?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);
}
}
答案 4 :(得分:18)
我知道上面的答案是正确的,但它们是在应用程序级别,为什么我们不使用$_SESSION["costumer_id"]
文件来设置过期时间?
.htaccess
答案 5 :(得分:14)
if (isSet($_SESSION['started'])){
if((mktime() - $_SESSION['started'] - 60*30) > 0){
//Logout, destroy session, etc.
}
}
else {
$_SESSION['started'] = mktime();
}
答案 6 :(得分:13)
使用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
答案 7 :(得分:10)
使用如下功能实际上很容易。它使用数据库表名称'sessions',字段'id'和'time'。
每当用户再次访问您的站点或服务时,您应调用此函数以检查其返回值是否为TRUE。如果它为FALSE,则用户已过期并且会话将被销毁(注意:此函数使用数据库类来连接和查询数据库,当然您也可以在函数内部或类似的内容中执行此操作):
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;
}
答案 8 :(得分:8)
在会话中存储时间戳
<?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
}
?>
答案 9 :(得分:7)
请使用包含在每个页面中的包含文件中的以下代码块。
$expiry = 1800 ;//session expiry required after 30 mins
if (isset($_SESSION['LAST']) && (time() - $_SESSION['LAST'] > $expiry)) {
session_unset();
session_destroy();
}
$_SESSION['LAST'] = time();
答案 10 :(得分:2)
对于初学者来说,PHP如何处理会话非常令人困惑。通过概述会话的工作方式,这可能对他们有帮助: how sessions work(custom-session-handlers)
答案 11 :(得分:0)
使用时间戳...
<?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>";
}
}
?>
我使用时间戳使用了20秒来暂停会话。
如果你需要30分钟加1800(30分钟,秒)......
答案 12 :(得分:0)
使用此类达30分钟
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");
}
}
答案 13 :(得分:0)
您可以直接使用数据库作为替代。我使用一个称为chk_lgn的数据库函数来完成它。
检查登录检查以查看是否已登录,并以此将检查的日期时间戳设置为用户的数据库行/列中的最后一个活动时间。
我也在那儿检查时间。目前,这对我有用,因为我在每个页面上都使用此功能。
P.S。我没有看到有人提出过一种纯粹的数据库解决方案。
答案 14 :(得分:0)
这让我大开眼界,克里斯托弗·克莱默(Christopher Kramer)2014年在 https://www.php.net/manual/en/session.configuration.php#115842
在基于debian的系统上,在运行时更改session.gc_maxlifetime并没有实际效果。 Debian通过设置session.gc_probability = 0来禁用PHP自己的垃圾收集器。相反,它每30分钟运行一次cronjob(请参阅/etc/cron.d/php5),以清理旧的会话。这个cronjob基本上会调查您的php.ini,并使用session.gc_maxlifetime的值来确定要清理的会话(请参阅/ usr / lib / php5 / maxlifetime)。 [...]
答案 15 :(得分:0)
这里可以设置时间
$lifespan = 1800;
ini_set('session.gc_maxlifetime', $lifespan); //default life time
答案 16 :(得分:-2)
只需存储当前时间,如果通过比较超过30分钟,则销毁当前会话。