Php 如何在会话超时时运行更新查询

Php 如何在会话超时时运行更新查询,php,session,cakephp,model-view-controller,session-timeout,Php,Session,Cakephp,Model View Controller,Session Timeout,我正在从事一个使用CakePHP2.8构建的项目。在登录时,我将一个标志设置为1,在注销时将其设置为0,这样一次就可以在一台计算机上登录帐户。在这一部分之前,它工作得很好 我面临的问题是会话超时。在会话超时时,如何在数据库中将标志设置为0,我感到困惑。是否有任何方法可以在会话超时时运行更新查询 我使用CORE配置文件设置会话超时限制,如下所示: Configure::write('Session', array( 'defaults' => 'php', 'timeout'

我正在从事一个使用CakePHP2.8构建的项目。在登录时,我将一个标志设置为1,在注销时将其设置为0,这样一次就可以在一台计算机上登录帐户。在这一部分之前,它工作得很好

我面临的问题是会话超时。在会话超时时,如何在数据库中将标志设置为0,我感到困惑。是否有任何方法可以在会话超时时运行更新查询

我使用CORE配置文件设置会话超时限制,如下所示:

Configure::write('Session', array(
    'defaults' => 'php',
    'timeout' => 30, // The session will timeout after 30 minutes of inactivity
    'cookieTimeout' => 1440, // The session cookie will live for at most 24 hours, this does not effect session timeouts
    'checkAgent' => false,
    'autoRegenerate' => true, // causes the session expiration time to reset on each page load
));
这是我的注销功能

public function logout() {
    $id = $this->Auth->User('id');
    $this->User->updateAll(array('WebLoggedIn'=>0), array('User.id'=>$id));
    $this->Auth->logout();
    // redirect to the home
    return $this->redirect('/');
}
那不行 这个问题的想法行不通。与会话相关的活动部分,以及问题中的配置是:

  • 存储在服务器上的文件,其中包含序列化的会话数据,每次写入会话时都会更新该文件
  • 一个标准的php cron作业,用于删除已过期的会话文件(请参见
    /etc/cron.d/php5
    或等效文件)
  • 浏览器cookie,它将用户的浏览器会话链接到服务器上的文件
当用户的会话时间结束时-这意味着他们提供的会话id与服务器上的文件不对应,或者他们只是没有提供会话cookie。在会话到期时没有“hey this session expired”事件,也不能保证用户会提供旧会话id供您检查其是否有效

工作提案 一个简单的解决方案(这也意味着幼稚且可能容易绕过)是不存储布尔值,而是在数据库中存储会话过期的时间。即,具有与此类似的代码:

// App Controller
public function beforeFilter()
{
    $userId = $this->Auth->user('id');
    if ($userId) {
        $this->User->updateAll(
            array('active_session_expires'=> time() + (30 * 60)), 
            array('User.id'=>$id)
        );
    }
}
在用户控制器中:

public function login() {
    if ($this->request->is('post')) {
        if ($this->Auth->login()) {
            if ($this->Auth->user('active_session_expires') > time()) {
                $this->Flash->error('You are still logged in somewhere else');
                return $this->logout();
            }

            $this->User->updateAll(
                array('active_session_expires'=> time() + (30 * 60)), 
                array('User.id'=> $this->Auth->user('id'))
            );
            return $this->redirect($this->Auth->redirectUrl());
        }
        $this->Flash->error(__('Invalid username or password, try again'));
    }
}

public function logout()
{
    $id = $this->Auth->User('id');
    if ($id) {
        $this->User->updateAll(
            array('active_session_expires'=> time()),
            array('User.id'=>$id)
        );
        $this->Auth->logout();
    }
    return $this->redirect('/');
}
即,每次他们做某事时,更新数据库以跟踪他们的活动。如果他们试图在现有会话到期之前登录,请立即注销。除了需要测试/修改此示例代码外,提供此示例代码是为了给您一个想法,而不一定是一个完整的工作解决方案


这与类似。

请检查此项。你可以在这里做一些回答,谢谢你的建议,但上述功能将在30分钟后踢出用户,即使用户是活跃的。我想在30分钟不活动的情况下结束会话。如果有任何建议@ad7six执行此操作,我认为您误读了答案,这不是真的
即使用户处于活动状态,上述功能也会在30分钟后将用户踢出。没有代码可以让用户注销,除非他们试图登录,并且只有尝试登录会话被注销。对不起,我弄错了,我看错了。但是,如果我使用上述代码,我如何检查用户是否在30分钟内处于非活动状态,那么它需要注销,并在那时重置标志@AD7six
那么它需要注销吗?不需要,这就是
Session.timeout
config设置的作用。如果您确实想按照您的要求执行操作,请阅读
active\u session\u expires
值,并根据需要使用该值。