在会话开始后更改gc_max_lifetime

时间:2013-07-30 00:36:01

标签: php zend-framework session garbage-collection remember-me

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

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

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

我正在使用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与垃圾收集不同,而且我长达一个月的remember_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';
        }

AND这是我的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"

1 个答案:

答案 0 :(得分:0)

对于数据库支持会话,您可以专门控制会话删除的行为。 gc_max_lifetime只是传递给gc()会话处理函数的参数。可以根据需要使用或忽略它。你只需要使用你想要的任何逻辑。

例如,您可以简单地向数据库添加一个字段,以确定这是“长”会话还是“短会话”。然后相应地更改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的{​​{1}}值,也可以使用INTERVAL X SECONDS。