Fra*_*nga 1 php caching fat-free-framework
如何将无脂肪框架会话设置为在不活动持续时间(例如 5 分钟)后过期?我的网络应用程序保持打开状态,直到用户注销。
首先,您需要了解 PHP 会话垃圾收集器的行为。默认情况下,它会在每 100 个请求(出于性能目的)时随机触发,查找过期的会话文件(默认值:1440s)并删除它们。
此外,您还需要知道某些 Linux 发行版(例如 Debian/Ubuntu)禁用此垃圾收集器并将其替换为自己的 cron 作业。
您可以开始检查您的 PHP 配置:
foreach (['gc_probability','gc_divisor','gc_maxlifetime'] as $k)
echo $k,'=',ini_get("session.$k"),'<br>';
Run Code Online (Sandbox Code Playgroud)
如果 GC 概率为 0,会话文件将永远不会被删除(或者可以被 Debian/Ubuntu 上的 cron 作业删除)。如果它不是 0,而是低(例如 1/100),会话文件将被删除一段时间(尝试刷新页面 100 次)。
理论上,您可以将概率设置为 1 (gc_probability=gc_divisor=1) 以在会话文件过期后立即将其删除。这适用于低流量的小型应用程序,但会影响大型应用程序的性能(假设 GC 需要针对每个请求扫描 1000 个或更多会话文件)。
处理此问题的最简洁、最便携的方法是自己使会话过期。每次加载用户会话数据时,请检查它最后一次出现在此处的时间,如果会话数据已过期,请清除它。
这是一个小例子:
$f3->TIMEOUT=7200;// define session timeout here (in seconds)
ini_set('session.gc_maxlifetime',$f3->TIMEOUT);// see note (*) below
ini_set('session.cookie_lifetime',$f3->TIMEOUT);// optional (**)
$f3->route('GET|POST|DELETE /session',function($f3){
// load session data
$data=&$f3->ref('SESSION.data');
// sign in on POST requests
if ($f3->VERB==='POST') {
$data=['user'=>'John','stamp'=>time()];
$f3->reroute();
}
// sign out on DELETE requests
if ($f3->VERB==='DELETE') {
// sign out
$data=NULL;
$f3->reroute();
}
// check if session has expired
if (is_array($data) && time()>$data['stamp']+$f3->TIMEOUT) {
$data=NULL;
}
// check if user is authenticated
if (is_array($data)) {
echo 'Welcome ',$data['user'],' last time we\'ve seen you was ',date(DATE_W3C,$data['stamp']);
echo '<form action="" method="post"><button>Sign out</button><input type="hidden" name="_method" value="DELETE"/></form>';
$data['stamp']=time();// update session stamp
} else
echo 'You\'re not authenticated';
echo '<form action="" method="post"><button>Authenticate as `John`</button></form>';
});
Run Code Online (Sandbox Code Playgroud)
当然,您最好将所有这些逻辑包装在一个专用类中。
(*) PHP GC maxlifetime 不应低于$f3->TIMEOUT,否则可能会干扰它。假设$f3->TIMEOUT等于 7200 并session.gc_maxlifetime设置为 1440(默认),您的用户会话有可能在 1440 和7200之间过期。 注意:在 Debian/Ubuntu 上,您应该在 php.ini 中设置此参数,否则 cron 作业清理会话文件不会知道它。
(**) 如果跳过这一行,会话 cookie 生存期默认为 0,这意味着“直到浏览器关闭”。见这里。