Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中发现会话已过期?_Php_Session_Session Cookies - Fatal编程技术网

如何在PHP中发现会话已过期?

如何在PHP中发现会话已过期?,php,session,session-cookies,Php,Session,Session Cookies,我正在尝试改进web应用程序的会话管理。我的主要问题是会话过期以及如何处理它。为此,我想知道会话是否仍然可用。我使用的是默认的基于文件的会话(PHP7.1、Apache2.4、Fedora/RHEL),它是基于cookie的 我发现会话GC在被调用时执行。它不是在脚本执行的开始或结束时发生的,而是在这个函数中发生的。对我来说奇怪的是,如果 Session SistSistar()/代码>,GC认为会话已过期,并且想删除相应的会话文件,$ysession将首先被定期填充,然后该文件将被删除。真令人

我正在尝试改进web应用程序的会话管理。我的主要问题是会话过期以及如何处理它。为此,我想知道会话是否仍然可用。我使用的是默认的基于文件的会话(PHP7.1、Apache2.4、Fedora/RHEL),它是基于cookie的

我发现会话GC在被调用时执行。它不是在脚本执行的开始或结束时发生的,而是在这个函数中发生的。对我来说奇怪的是,如果<代码> Session SistSistar()/代码>,GC认为会话已过期,并且想删除相应的会话文件,$ysession将首先被定期填充,然后该文件将被删除。真令人惊讶

在这种情况下,只有下面的下一个请求会导致空$\会话。我希望之前的调用会出现这种情况——删除文件的调用。因此,如果我想知道当前请求中的会话是否已过期,我必须检查在调用
session\u start()
之后会话文件是否仍然存在。我觉得这很奇怪

除了查看文件系统,还有其他或更好的方法检查会话是否已过期吗?

我想我可以检查$\u会话是否为空,以确定会话是否已续订,但这显然是不可能的


更新:我发现了以下关于该问题的错误报告:和。还有一个关于过期问题的问题。当前PHP源代码:调用


您可能希望使用此脚本(非真实设置仅用于测试目的):

ini_集('session.gc_maxlifetime',2);//会话在2秒后过期
ini_集('session.gc_除数',1);//立即删除过期的会话文件
ini_集('session.save_path','/some/safe/path/for/testing');//服务器必须可以访问
//ini_集('session.use_strict_mode',true);//取消注释如果id应该更新,这里有什么区别
回显“会话启动调用之前的会话文件
”; listSessionFiles(); 会话_start(); 回显“会话启动调用后的会话文件
”; listSessionFiles(); 回声“
”; 回显“会话id:”。会话id()。“
”; echo“会话内容:”。打印\u r($\u会话,true); $\u会话['x']=time();//用一些东西填充会话 函数listSessionFiles(){ 回声“
    ”; $none=true; $dir=dir(ini_get('session.save_path'); 而($entry=$dir->read()){ if(preg_匹配(“/^sess/”,$entry)){ 回显“
  • ”$entry。”
  • ”; $none=假; } } $dir->close(); 如果($none)回显“
  • none
  • ”; 回声“
”; }

只需重新加载页面几次。至少等待两秒钟以上。否则会话不会过期。

规避此问题的一种方法是使用具有特定生存期(低于会话生存期)的cookie。如果cookie过期,它将不会被发送到服务器。当调用
session\u start()
时,PHP将创建一个新会话,因此$\u会话将为空


这可能足以发现会话不可用。尽管在PHP中无法区分会话是否已过期或出现任何错误。您可以直接判断没有可用的会话数据,然后执行相应的操作(除其他外,还可以销毁新创建的空会话)。

将GC设置为在每个请求上运行是毫无意义的。PHP会话没有实际有效期,它们只有最短的生存期。如果您想要最大生存期,那么您应该自己实现它-在会话中存储上一次访问时间,在下一次访问时与当前时间进行比较,并决定是继续还是终止此会话。@CBroe该脚本只是用来玩的。当然,我不使用这些设置。不,我不想要最长的寿命。我只是想知道会话是否已过期。事实上,就像@CBroe所说的,
将GC设置为在每个请求上运行是毫无意义的。
此外,由于需要磁盘I/o,它可能会导致延迟。@RaymondNijland我知道。剧本只是为了尝试一下。但是,问题不受这些设置的影响。“我发现,会话GC是在调用session_start()时执行的。它不是在脚本执行的开始或结束时执行的,而是在这个函数中执行的。”-这是经过验证的事实(通过检查PHP源代码),还是仅仅是一个假设,因为它“感觉像这样”从你所看到的?我认为,2秒钟的寿命也可能会扭曲你的结果/观察结果。除非在半现实的条件下进行测试,否则我认为这根本不能证明什么。
ini_set('session.gc_maxlifetime', 2); // Session gets expired after 2 seconds
ini_set('session.gc_divisor',     1); // Delete expired session files immediately
ini_set('session.save_path',      '/some/safe/path/for/testing'); // Must be accessible for the server
//ini_set('session.use_strict_mode', true); // Uncomment if the id should be renewed, what makes no difference here

echo "Session files before session_start call<br>";
listSessionFiles();

session_start();

echo "Session files after session_start call<br>";
listSessionFiles();

echo "<hr>";

echo "Session id: "      . session_id() . "<br>";
echo "Session content: " . print_r($_SESSION, true);
$_SESSION['x'] = time(); // Populate the session with something 


function listSessionFiles() {
    echo "<ul>";
    $none = true;
    $dir  = dir(ini_get('session.save_path'));        
    while ($entry = $dir->read()) {
        if (preg_match('/^sess_/', $entry)) {
            echo "<li>" . $entry . "</li>";
            $none = false;
        }
    }
    $dir->close();
    if ($none) echo "<li>None</li>";
    echo "</ul>";
}