Zend会话和命名空间过期


Zend Session and Namespace Expiries

我有两个领域需要会话管理,有两个不同的到期时间:

  • 行政区域-20分钟
  • 预订区域-3分钟

使用Zend_Session,如何为同一用户管理两者?

需要注意的是,预订区域的行为与Ticketmaster非常相似,在Ticketmaster中,将预订准确性保持在第二位至关重要。

我目前的实现使用了Zend_Session_SaveHandler_DbTable,如果可能的话,我想坚持使用它。

我将来自主会话表的Session_ID存储在预订表上以指示预订。这样做效果很好,因为它允许我使用垃圾收集来清理废弃的会话(我每分钟都有一个cron触发垃圾收集)。

我对这个实现的问题是,考虑到时差,我不知道如何管理行政区的会话。

我认为您需要一个应用程序级别的东西来管理这些保留,而不是依赖于会话本身。当会话过期时,很难"做事",我认为会话并不是真正设计用来依赖这种功能的。

我建议您创建一个单独的表来保存预订令牌。它们将有一个唯一的"token"散列作为主键,一个"expires"日期,可能还有一个可选的用户ID。您不将Session_ID存储在保留表上,而是存储具有相同约束的令牌(因此删除令牌可以释放保留)。您添加了一个使令牌过期的额外cron作业——这可以像执行DELETE FROM reservation_tokens WHERE expires < NOW()查询一样简单。在会话中,您存储令牌,检查令牌上的过期时间将告诉您保留是否仍然有效。

这样,您的预订到期时间就不再取决于会话的到期时间。如果登录用户再次登录(在预订到期之前),它还可以允许他们拥有相同的预订。

至于管理登录,我过去采用的一种方法是在用户进行身份验证时简单地延长会话到期时间。这很容易做到,只需在有效登录后:

// assuming $result is a Zend_Auth_Result
if ($result->isValid()) {
    // extend the user's session
    $lifetime = 1200;
    ini_set('session.cookie_lifetime', $lifetime);
    Zend_Session::rememberMe($lifetime);
}

如果您已经实现了预订令牌解决方案,那么拥有更长的会话就不会再导致您的预订出现问题。

您可以在Zend_Session_Namespace中使用setExpirationSeconds方法。

$session->setExpirationSeconds(10);

10秒后到期。