会话超时是一个必须在代码中实现的概念,如果您需要严格的保证;这是the only way,你可以绝对肯定,在X分钟的不活动之后,任何一个会话都不会存活下来.
如果稍微放宽这一要求是可以接受的,并且您可以设置lower bound而不是严格限制持续时间,那么您可以轻松地做到这一点,而无需编写自定义逻辑.
If您的会话是通过cookie实现的(它们可能是),if如果客户端不是恶意的,您可以通过调整某些参数来设置会话持续时间的上限.如果您使用PHP的默认会话处理cookie,设置session.gc_maxlifetime
和session_set_cookie_params
应该适用于您,如下所示:
// server should keep session data for AT LEAST 1 hour
ini_set('session.gc_maxlifetime', 3600);
// each client should remember their session id for EXACTLY 1 hour
session_set_cookie_params(3600);
session_start(); // ready to go!
这是通过配置服务器使会话数据保持至少一个小时的不活动状态,并指示客户端在相同的时间跨度后"忘记"会话id来实现的.Both of these steps are required to achieve the expected result.
如果您不告诉客户端在一小时后忘记它们的会话ID(或者如果客户端是恶意的并 Select 忽略您的指令),它们将继续使用相同的会话ID,其有效持续时间将是不确定的.这是因为在服务器端生命周期已过期的会话不会立即被垃圾收集,而只会被垃圾收集whenever the session GC kicks in次.
GC是一个潜在的昂贵过程,因此通常概率相当小,甚至为零(获得大量点击量的网站可能会完全放弃概率GC,而计划每X分钟在后台进行一次GC).在这两种情况下(假设不合作的客户端),有效会话生存期的下限将是session.gc_maxlifetime
,但上限将是不可预测的.
如果您没有将session.gc_maxlifetime
设置为相同的时间跨度,那么服务器可能会在此之前丢弃空闲会话数据;在这种情况下,仍然记得其会话ID的客户端将显示它,但是服务器将找不到与该会话相关联的数据,从而有效地表现为会话刚刚开始.
通过使用自定义逻辑,还可以将upper bound置于会话不活动状态,使事情完全可控;加上上面的下限,这将导致一个严格的设置.
通过将上限与会话数据的其余部分一起保存来实现这一点:
session_start(); // ready to go!
$now = time();
if (isset($_SESSION['discard_after']) && $now > $_SESSION['discard_after']) {
// this session has worn out its welcome; kill it and start a brand new one
session_unset();
session_destroy();
session_start();
}
// either new or old, it should live at most for another hour
$_SESSION['discard_after'] = $now + 3600;
到目前为止,我们根本不关心每个会话id的确切值,只关心数据应该存在到我们需要的时候.请注意,在会话ID对您很重要的情况下(不太可能),必须注意在需要时使用session_regenerate_id
重新生成会话ID.