我需要保持一个会话存活30分钟,然后销毁它。


当前回答

只存储当前时间,如果它超过30分钟比较然后销毁当前会话。

其他回答

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

<IfModule mod_php5.c>
    #Session timeout
    php_value session.cookie_lifetime 1800
    php_value session.gc_maxlifetime 1800
</IfModule>

请使用以下代码块在您的包括文件加载在每一页。

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

使用下面这样的函数其实很简单。它使用数据库表名'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;
}

这让我大开眼界,克里斯托弗·克莱默在2014年写的 https://www.php.net/manual/en/session.configuration.php#115842

在debian(基于)系统上,更改会话。Gc_maxlifetime在运行时没有实际影响。Debian通过设置session.gc_probability=0禁用PHP自己的垃圾收集器。相反,它有一个每30分钟运行一次的cronjob(参见/etc/cron.d/php5)来清理旧的会话。这个cronjob基本上会查看你的php.ini并使用session的值。Gc_maxlifetime来决定清理哪些会话(参见/usr/lib/php5/maxlifetime)。[…]

您可以直接使用DB作为替代。我使用一个DB函数来做这件事,我称之为chk_lgn。

检查登录检查,看看他们是否登录,在这样做的时候,它将检查的日期时间戳设置为用户db行/列中的最后一个活动。

我也会核对时间。这对我来说是有效的,因为我对每个页面都使用这个函数。

附注:我所见过的人中,没有人建议使用纯DB解决方案。