如何设置一个无胖的框架会话在一段时间(比如5分钟)不活动后过期?我的网络应用程序一直处于打开状态,直到用户退出。
答案 0 :(得分:4)
首先,您需要了解PHP会话garbage collector行为。默认情况下,它会在每100个请求中随机触发(出于性能目的),查找过期的会话文件(默认值:1440s)并将其删除。
此外,你需要知道一些Linux发行版(例如Debian / Ubuntu)disable这个垃圾收集器并用它们自己的cron作业替换它。
您可以开始检查您的PHP配置:
foreach (['gc_probability','gc_divisor','gc_maxlifetime'] as $k)
echo $k,'=',ini_get("session.$k"),'<br>';
如果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>';
});
当然,您最好将所有这些逻辑包装在一个专门的课程中。
(*)PHP GC maxlifetime不应低于$f3->TIMEOUT
,否则可能会干扰它。我们说$f3->TIMEOUT
等于7200而session.gc_maxlifetime
设置为1440(默认值),您的用户会话有可能在1440到7200之间过期。注意:在Debian / Ubuntu上,你应该在php.ini中设置此参数,否则清理会话文件的cron作业不会意识到它。
(**)如果您跳过此行,会话cookie生存期默认为0,这意味着&#34;直到浏览器关闭&#34;。请参阅here。