【问题标题】:Change gc_max_lifetime AFTER session is started会话启动后更改 gc_max_lifetime
【发布时间】:2013-07-30 00:36:00
【问题描述】:

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

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

我遇到的问题是我不想在表中累积大量会话数据并影响服务器延迟。为了做到这一点,我想在某人匿名时将其会话存储 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"

【问题讨论】:

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


    【解决方案1】:

    对于数据库支持的会话,您可以专门控制会话删除的行为。 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()gc_max_lifetime 值,也可以在此处使用INTERVAL X SECONDS。

    【讨论】:

    • 我在 Zend 的会话工具中使用会话表中的自定义列时遇到了困难。但是这个答案启发我在他们登录时简单地更新会话。不幸的是,我也无法使用登录它们的相同逻辑更新会话。所以我设置了一个会话变量,并在下一页加载时检查它:` 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 = '月'; }`
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 2015-10-09
    相关资源
    最近更新 更多