2013-07-30 31 views
0

我处于(唯一的?)情况,我希望登录的人尽可能保持登录状态。理想情况下,一个月(营销需要一年)。我们将会话数据存储在数据库中,而不是默认文件。更改gc_max_lifetime会话启动后

我们不存储任何个人信息或任何其他可能存在安全风险的内容。

我遇到的问题是我不想在表中堆积大量的会话数据并影响服务器延迟。为了做到这一点,我想以匿名方式储存某人的会话时间为86400秒(1天),但在登录后将其更改为2592000秒(30天)。

I'米使用Zend Framework 1.12,并有我的application.ini如下:

resources.session.gc_maxlifetime = 86400 
resources.session.remember_me_seconds = 2592000 
resources.session.saveHandler.class = "Zend_Session_SaveHandler_DbTable" 
resources.session.saveHandler.options.name = "session" 
resources.session.saveHandler.options.primary[] = "session_id" 
resources.session.saveHandler.options.primary[] = "save_path" 
resources.session.saveHandler.options.primary[] = "name" 
resources.session.saveHandler.options.primaryAssignment[] = "sessionId" 
resources.session.saveHandler.options.primaryAssignment[] = "sessionSavePath" 
resources.session.saveHandler.options.primaryAssignment[] = "sessionName" 
resources.session.saveHandler.options.modifiedColumn = "modified" 
resources.session.saveHandler.options.dataColumn = "session_data" 
resources.session.saveHandler.options.lifetimeColumn = "lifetime" 

当我第一次来到现场的寿命设定为“86400”,但一旦我登录它不会改变。我认为remember_me与垃圾收集不同,而且我的一个月的记忆_me是没有意义的,因为它将在一天之后收集,从而破坏会话。所以,我尝试在登录时修改它。这是我的登录逻辑:

$adapter = new Activejunky_Auth_Adapter_Doctrine($values['username'], $values['password']); 
    $auth = Zend_Auth::getInstance(); 
    $sessionOptions = array(
     'gc_maxlifetime'   => 2592000, 
     'remember_me_seconds' => 2592000, 
    ); 
    Zend_Session::setOptions($sessionOptions); 
    Zend_Session::rememberMe(60 * 60 * 24 * 30); 
    error_log('you working?'); 
    Zend_Session::start(); 

    $result = $auth->authenticate($adapter); 

    if ($result->isValid()) 
    { 
     $user = $adapter->getResultObject(); 
     $user->last_login = time(); 
     $user->save(); 

     //STORE USER INFO 
     $authStorage = $auth->getStorage(); 
     $authStorage->write($user->toArray()); 

那,然而,仍然不起作用。我登录没问题,但终身仍然设置为86400.有没有办法做到这一点?还是我坚持甚至尝试?

编辑

因此,它更易于阅读,这里就是我所做的。在页面上后,他们已经登录:

  $aj = new Zend_Session_Namespace('aj'); 
      if($aj->lifetime == 'day') 
     { 
      $db = Zend_Db_Table::getDefaultAdapter(); 
      $sid = Zend_Session::getId(); 
      $where = $db->quoteInto('session_id = ?', Zend_Session::getId()); 
      $db->update('session', array('lifetime' => 2592000), $where); 
      $aj->lifetime = 'month'; 
     } 

,这里是我的application.ini:

resources.session.gc_maxlifetime = 7200 
resources.session.remember_me_seconds = 2592000 
resources.session.saveHandler.class = "Zend_Session_SaveHandler_DbTable" 
resources.session.saveHandler.options.name = "session" 
resources.session.saveHandler.options.primary[] = "session_id" 
resources.session.saveHandler.options.primary[] = "save_path" 
resources.session.saveHandler.options.primary[] = "name" 
resources.session.saveHandler.options.primaryAssignment[] = "sessionId" 
resources.session.saveHandler.options.primaryAssignment[] = "sessionSavePath" 
resources.session.saveHandler.options.primaryAssignment[] = "sessionName" 
resources.session.saveHandler.options.modifiedColumn = "modified" 
resources.session.saveHandler.options.dataColumn = "session_data" 
resources.session.saveHandler.options.lifetimeColumn = "lifetime" 
resources.view.doctype = "HTML5" 
resources.view.language = "en" 

回答

0

对于数据库备份会话,您可以具体控制删除会话的行为。 gc_max_lifetime只是一个传递给您的会话处理函数的参数。它可以被使用或忽略,只要你喜欢。你只需要使用你想要的任何逻辑。

例如,您可以简单地向数据库添加一个字段,以确定这是“长”会话还是“短会话”。然后相应地更改您的DELETE SQL。因此,像这样:

DELETE FROM sessions 
WHERE 
    (long_session = 1 AND timestamp_field < DATE_SUB(NOW(), INTERVAL 30 DAYS)) OR 
    (long_session = 0 AND timestamp_filed < DATE_SUB(NOW(), INTERVAL 1 DAY)) 

在这里,如果你想使用gc_max_lifetime值传递给gc()你可以使用间隔X秒为好。

+0

我在使用会话表中的自定义列的Zend会话工具时遇到了困难。但是这个答案启发了我在登录时简单地更新会话。不幸的是,我在更新会话时也遇到了麻烦,因为它使用与登录它们相同的逻辑来更新会话。所以,我设置了一个会话变量,并在下一页加载时检查它: '\t if($ aj-> lifetime =='day' ) \t { \t \t $ db = Zend_Db_Table :: getDefaultAdapter(); \t \t $ sid = Zend_Session :: getId(); \t \t $ where = $ db-> quoteInto('session_id =?',Zend_Session :: getId()); $ db-> update('session',array('lifetime'=> 2592000),$ where); \t \t $ aj-> lifetime ='month'; \t}' – user2188915