如何在PHP中发现会话已过期?
我正在尝试改进web应用程序的会话管理。我的主要问题是会话过期以及如何处理它。为此,我想知道会话是否仍然可用。我使用的是默认的基于文件的会话(PHP7.1、Apache2.4、Fedora/RHEL),它是基于cookie的 我发现会话GC在被调用时执行。它不是在脚本执行的开始或结束时发生的,而是在这个函数中发生的。对我来说奇怪的是,如果<代码> Session SistSistar()/代码>,GC认为会话已过期,并且想删除相应的会话文件,$ysession将首先被定期填充,然后该文件将被删除。真令人惊讶 在这种情况下,只有下面的下一个请求会导致空$\会话。我希望之前的调用会出现这种情况——删除文件的调用。因此,如果我想知道当前请求中的会话是否已过期,我必须检查在调用如何在PHP中发现会话已过期?,php,session,session-cookies,Php,Session,Session Cookies,我正在尝试改进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>";
}