PHP 会话在 40 分钟后到期

Posted

技术标签:

【中文标题】PHP 会话在 40 分钟后到期【英文标题】:PHP session expiring after 40 minutes 【发布时间】:2015-04-15 05:07:10 【问题描述】:

我编写了这段代码来管理会话,以便它们在浏览器关闭或用户在定义的时间(2 小时)内不活动时过期。然而,似乎会话在 40 分钟不活动后到期,我真的不明白这怎么可能。如果我的代码失败,我希望它们应该持续 1440 秒(24 分钟)。

define("MY_SESSION", "mysession");
define("SESSION_DURATION", 7200);
function my_session_start() 
    if (session_status() != php_SESSION_NONE)
        return;
    ini_set('session.gc_maxlifetime', SESSION_DURATION);
    ini_set('session.cookie_lifetime', 0);
    session_set_cookie_params(0);
    session_name(MY_SESSION);
    session_start();
    if ((!isset($_SESSION['EXPIRES'])) || ($_SESSION['EXPIRES'] < time())) 
        $_SESSION = array();
        session_unset();
        session_destroy();
        session_start();
    
    $_SESSION['EXPIRES'] = time() + SESSION_DURATION;
    if (isset($_SESSION['REGENERATE'])) 
        $_SESSION['REGENERATE']++;
        if ($_SESSION['REGENERATE'] >= mt_rand(90,100)) 
            $_SESSION['REGENERATE'] = 0;
            session_regenerate_id(true);
        
    
    else 
        $_SESSION['REGENERATE'] = 0;
        session_regenerate_id(true);
    

我在每个 PHP 文件中放置了my_session_start()。 我在共享服务器上,但ini_set() 未被阻止,通过在my_session_start() 之后启动phpinfo(),我可以看到session.gc_maxlifetime 本地值被设置为7200(而主值是1440)。 session.gc_probabilitysession.gc_divisor 保留其默认值(分别为 1 和 100)。 我还在 90-100 个页面加载/AJAX 调用的随机基础上重新生成会话 ID,但这并不重要,因为我也尝试注释掉该部分,但它并没有解决问题。

那么,我的代码有问题吗?分钟数从何而来,我的意思是为什么是 40 分钟?

【问题讨论】:

在 [how to expire PHP session after 30m][1] 上查看此答案。 [1]:***.com/questions/520237/… 这几乎就是我对我的代码所做的事情,问题肯定不是来自除数和概率,因为我至少尝试了 5 次:39 分钟不活动 -> 会话活动,41 分钟不活动 - > 会话已死。仍然想知道为什么,为什么要 40 分钟 40 分钟谜团解开:根据所附文章中的评论,我在主机服务器上观看了“会话文件”。 40分钟后,它消失了。在共享帐户上,我们的网络主机似乎在这些会话文件夹上设置了自定义 cron 作业。这就解释了为什么重定向save_path 有效——它将会话文件从他们的cron 作业solutionfactor.net/blog/2014/02/08/… 下取出(并为启动canvas.seattlecentral.edu/courses/980464/pages/… 产生一些额外的安全性)。 【参考方案1】:

所以我终于想出了如何解决这个问题。 解决方案是更改会话文件保存文件夹:

ini_set('session.save_path', "/the/new/path/to/sessions/"); //DEFAULT: /var/lib/php5

这样做意味着可能会查看会话文件,因此我添加了包含以下内容的 .htaccess 文件:

deny from all

在“/the/new/path/to/sessions/”文件夹中。所以从服务器外部看不到任何东西。

另外,我必须添加一个新的会话垃圾收集功能:

function clear_old_sessions() 
    $folder = "/the/new/path/to/sessions/";
    $files = scandir($folder);
    for ($i = 0; $i < count($files); $i++) 
        $file = $folder . $files[$i];
        if (is_file($file))
            if (substr($files[$i], 0, 5) == "sess_")
                if ((filemtime($file) + SESSION_DURATION) < time()) // SESSION_DURATION previosuly defined as 7200 (seconds)
                            unlink($file);
    

【讨论】:

虽然您的解决方案也对我有用(感谢您在 5 年前发布此内容!),但它是此处链接提供的其他部分的更大难题的一部分。顺便说一句,我还读到重新定位的save_path 在网络访问之外更安全,因此在上面创建的ergo ---例如---public_html 文件夹的兄弟。 solutionfactor.net/blog/2014/02/08/… canvas.seattlecentral.edu/courses/980464/pages/… 当然还有:php.net/manual/en/session.configuration.php 当然,如果您的主机允许您在 public_html 文件夹之外工作,那么会话文件应该放在外面。吃掉了我写代码的时间,不幸的是,我不得不在一个不允许我访问 public_html 之外的任何东西的共享主机上工作,所以我不得不将包含会话文件的文件夹放在其中,并使用 .htaccess 解决安全问题文件

以上是关于PHP 会话在 40 分钟后到期的主要内容,如果未能解决你的问题,请参考以下文章

控制会话的到期

范围 codeigniter 会话到期

如何在 Laravel 中设置会话超时?

常规会话管理和常见超时

PHP - 将会话变量设置为在 30 分钟后过期 [重复]

几分钟后 PHP 会话超时