Php Zend会话和命名空间过期

Php Zend会话和命名空间过期,php,zend-framework,zend-session,Php,Zend Framework,Zend Session,我有两个需要会话管理的区域,有两个不同的到期时间: 行政区-20分钟 预订区-3分钟 使用Zend_会话,如何为同一用户管理这两个会话 需要注意的是,预订区域的行为非常类似于Ticketmaster,在Ticketmaster中,将预订准确度保持在第二位是至关重要的 我当前的实现使用了Zend\u Session\u SaveHandler\u DbTable,如果可能的话,我希望继续使用它 我正在将主会话表中的Session\u ID存储在预订表中,以指示预订。这很好,因为它允许我使用垃圾

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

  • 行政区-20分钟
  • 预订区-3分钟
使用
Zend_会话
,如何为同一用户管理这两个会话

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

我当前的实现使用了
Zend\u Session\u SaveHandler\u DbTable
,如果可能的话,我希望继续使用它

我正在将主会话表中的
Session\u ID
存储在预订表中,以指示预订。这很好,因为它允许我使用垃圾收集来清理废弃的会话(我每分钟都有一个cron触发垃圾收集)


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

您可以在Zend_会话名称空间中使用
setExpirationSeconds
方法

$session->setExpirationSeconds(10);

用于在10秒内到期。

您可以在Zend_会话_命名空间中使用
setExpirationSeconds
方法

$session->setExpirationSeconds(10);

10秒后到期。

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

我建议您创建一个单独的表来保存预订令牌。它们将有一个唯一的“令牌”散列作为主键,一个“过期”日期,可能还有一个可选的用户ID。您不在保留表上存储会话ID,而是存储令牌,并使用相同的约束(因此删除令牌释放保留)。您添加了一个额外的cron作业,使令牌过期-这可能非常简单,只需执行一个
DELETE FROM reservation\u tokens WHERE expires
查询。在会话中存储令牌,检查令牌的过期时间将告诉您保留是否仍然有效

这样,您的预订到期不再依赖于会话到期。它还允许登录用户再次登录(在保留过期之前)时仍保留相同的保留

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

// 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);
}

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

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

我建议您创建一个单独的表来保存预订令牌。它们将有一个唯一的“令牌”散列作为主键,一个“过期”日期,可能还有一个可选的用户ID。您不在保留表上存储会话ID,而是存储令牌,并使用相同的约束(因此删除令牌释放保留)。您添加了一个额外的cron作业,使令牌过期-这可能非常简单,只需执行一个
DELETE FROM reservation\u tokens WHERE expires
查询。在会话中存储令牌,检查令牌的过期时间将告诉您保留是否仍然有效

这样,您的预订到期不再依赖于会话到期。它还允许登录用户再次登录(在保留过期之前)时仍保留相同的保留

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

// 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_会话_命名空间的问题在于我无法使用垃圾收集来管理它们的过期(请参见
Zend_会话_SaveHandler_DbTable::gc())
)。它只关心外部会话的生存期。
Zend\u session\u名称空间的问题在于我无法使用垃圾收集来管理它们的过期(请参见
Zend\u session\u SaveHandler\u DbTable::gc())
)。它只关心外部会话的生命周期。你能再解释一下你对被放弃的会话做了什么吗?您的cron作业是否对会话ID刚刚过期的预订做了一些处理?@cron作业只需每分钟调用会话垃圾收集(请参阅
Zend\u session\u SaveHandler\u DbTable::gc()
)。垃圾收集会删除会话记录,因为我对保留表上的会话\u ID有innoDB外键约束,它反过来会将会话ID外键设置为NULL,从而删除保留。用户在进行保留时是否登录到站点?@timfuntain一般来说,用户在未登录的情况下在公共端进行预订,因此他们唯一的会话将是预订会话。也就是说,登录到管理区域的用户可以浏览到公共端并进行预订。不过,这不是一个常见的用例,如果我需要阻止这种情况以帮助解决更大的问题,那么这是可以接受的。如果我可以为一个用户设置两个会话,使用不同的生存时间(3分钟和20分钟),我会被设置。这似乎是不可能的。你能再解释一下你是如何处理这些被放弃的课程的吗?你的cron工作对预订有帮助吗