0

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

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

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

我正在使用 zend 框架 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';
        }

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

1 回答 1

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传递给的值,也可以在此处使用 INTERVAL X SECONDS gc()

于 2013-07-30T00:52:36.253 回答