当前位置:  开发笔记 > 编程语言 > 正文

如何在30分钟后使PHP会话到期?

如何解决《如何在30分钟后使PHP会话到期?》经验,为你挑选了10个好方法。

我需要让会话保持30分钟,然后将其销毁.



1> Gumbo..:

您应该实现自己的会话超时.其他人提到的两个选项(session.gc_maxlifetimesession.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.因此,对于无法进行atime跟踪的文件系统,您不会遇到问题.

因此,当会话本身仍然被认为是有效的时,可能还会发生会话数据文件被删除,因为会话数据最近没有更新.

第二个:

session.cookie_lifetime
session.cookie_lifetime指定发送到浏览器的cookie的生命周期(以秒为单位).[...]

恩,那就对了.这仅影响cookie生存期,会话本身可能仍然有效.但是服务器的任务是使会话无效,而不是客户端.所以这对任何事都没有帮助.实际上,将session.cookie_lifetime设置为0会使会话的cookie成为真正的会话cookie,该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,以避免对会话固定等会话的攻击:

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);

如果您希望在活动 30分钟后而不是在启动后30分钟后使会话setcookie过期,则还需要使用过期time()+60*30以使会话cookie保持活动状态.


@Metropolis:使用类似于`$ _SESSION ['LAST_ACTIVITY']的类似`$ _SESSION ['CREATED']`,其中存储用户上次活动的时间,但每次请求都会更新该值.现在,如果该时间与当前时间的差异大于1800秒,则会话的使用时间不超过30分钟.
@Gumbo - 我有点困惑,你不应该将你的代码与`ini_set('session.gc-maxlifetime',1800)结合使用吗?否则,您的会话信息可能会在您的会话仍然有效时被销毁,至少如果ini设置是标准的24分钟.或者我错过了什么?
@jeron:是的,你应该.但请注意,如果使用会话保存处理程序`files`,*session.gc\_maxlifetime*取决于文件的最后修改日期.因此*session.gc\_maxlifetime*应该至少等于此自定义到期处理程序的生命周期.
如果你想检查"非活动时间",你怎么能改变这个?换句话说,用户登录,只要他们继续使用该站点,它就不会将其注销.但是,如果它们在30分钟内不活动,它会将它们记录下来吗?
@Metropolis:`session_unset`与`$ _SESSION = array()`的作用相同.
@Gumbo:当询问有关会话的类似问题时,会大量引用/链接此问题。不幸的是,您在2月3日的评论中做出的“ 0”设置与以秒为单位的长设置有很大不同的怪癖,几乎在其他任何地方都不清楚。您介意在回答中参考它吗?还是做出CW之类的答案,以便我们可以将此问答作为所有Session FUD的重要资源?
这是一个很好的答案,有一点需要补充的是session_unset()似乎已被弃用,而有利于$ _SESSION = array(); 请参阅此处的说明:http://php.net/manual/en/function.session-destroy.php

2> Rafee..:

PHP会话在30分钟内到期的简单方法.

注意:如果你想改变时间,只需用你想要的时间改变30,不要改变*60:这将给出分钟.


在几分钟内:(30*60)
在几天内:(n*24*60*60)n =没有天数


的login.php




    
Username
Password

HomePage.php

Click Here to Login";
    }
    else {
        $now = time(); // Checking the time now when home page starts.

        if ($now > $_SESSION['expire']) {
            session_destroy();
            echo "Your session has expired! Login here";
        }
        else { //Starting this else one [else1]
?>
            
            
                Welcome
                Log out";
                ?>
            

LogOut.php



在MVC成为常态的当今时代,逻辑和演示相结合是不明智的.
@stillstanding为自己说话[笑]我认为MVC是一种憎恶.

3> Ross..:

这是在一段时间后将用户注销吗?设置会话创建时间(或到期时间),然后检查每个页面上的负载可以处理它.

例如:

$_SESSION['example'] = array('foo' => 'bar', 'registered' => time());

// later

if ((time() - $_SESSION['example']['registered']) > (60 * 30)) {
    unset($_SESSION['example']);
}

编辑:我觉得你的意思是别的.

您可以使用session.gc_maxlifetimeini设置在一定生命周期后删除会话:

编辑: ini_set('session.gc_maxlifetime',60*30);


会话cookie生命周期存在一些问题,最值得注意的是,它依赖于客户端来强制执行它.cookie的生命周期是允许客户端清理无用/过期的cookie,不要与任何安全相关的东西混淆.

4> Pablo Pazos..:

这篇文章展示了几种控制会话超时的方法:http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions

恕我直言第二个选择是一个很好的解决方案



5> Touqeer Shaf..:

我明白上面的答案是正确的,但它们是在应用程序级别,为什么我们不只是使用.htaccess文件来设置过期时间?


    #Session timeout
    php_value session.cookie_lifetime 1800
    php_value session.gc_maxlifetime 1800



6> middus..:
if (isSet($_SESSION['started'])){
    if((mktime() - $_SESSION['started'] - 60*30) > 0){
        //Logout, destroy session, etc.
    }
}
else {
    $_SESSION['started'] = mktime();
}



7> Wallace Maxt..:

使用功能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



8> Torsten Bart..:

使用如下功能实际上很容易.它使用数据库表名称'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;
}



9> 小智..:

在会话中存储时间戳


 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分钟)

 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
}
?>



10> lnepal..:

请在包含在每个页面中的包含文件中使用以下代码块.

$expiry = 1800 ;//session expiry required after 30 mins
    if (isset($_SESSION['LAST']) && (time() - $_SESSION['LAST'] > $expiry)) {
        session_unset();
        session_destroy();
    }
    $_SESSION['LAST'] = time();

推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有