lunux2008 发表于 2013-11-1 20:40:15

CI 数据库SESSION失效问题的解决方法

本帖最后由 lunux2008 于 2013-11-1 20:40 编辑

1.首先这不是一个常见问题,传统刷页面的方式不会遇到
2.同一时间只有一个AJAX请求的时候也不会遇到
3.同一时间有两个或两个以上AJAX请求必然遇到

配置文件:
$config['sess_expiration']= 30;             //设置session的有效期是30秒
$config['sess_time_to_update']   = 5;   //session更新间隔是5秒

遇到的问题是:
每隔2秒钟,同时发起2个AJAX请求控制器的两个不同ACTION,每当到5秒钟 更新SESSION的时候,SESSION就失效了。

---------------------------------------------------------------
    function sess_update()
    {
      if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)
      {
            return;
      }
      $old_sessid = $this->userdata['session_id'];
      $new_sessid = '';
      while (strlen($new_sessid) < 32)
      {
            $new_sessid .= mt_rand(0, mt_getrandmax());
      }
      $new_sessid .= $this->CI->input->ip_address();
      $new_sessid = md5(uniqid($new_sessid, TRUE));

      $this->userdata['session_id'] = $new_sessid;
      $this->userdata['last_activity'] = $this->now;
      $cookie_data = NULL;

      if ($this->sess_use_database === TRUE)
      {
            $cookie_data = array();
            foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
            {
                $cookie_data[$val] = $this->userdata[$val];
            }

            $this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid)));
      }

      $this->_set_cookie($cookie_data);
    }

--------------------------------------------------------------

看了一下 session.php 文件的代码,在update() 方法里最后这句,它会用新生成的session_id 替换原来的session_id,在数据库里会替换,同时把新的session_id放到cookie发到客户端,期望的是客户端下次用session_id来请求。但是如果是同时发出了两个AJAX请求,那么第一个到达的AJAX请求会执行到修改库里的SESSION_ID这里,新的SESSION_ID会写到客户端,但是第二个到达的AJAX还是在用老的SESSION_ID来访问,这个时候 用老的SESSION_ID到库里查数据当然结果是空的,然后会给第二个到达的AJAX请求创建一个新的空的SESSION,并又给客户端发出一个了更新的SESSION_ID。这一轮结束之后,SESSION就失效了。

解决的办法是
1.$this->userdata['session_id'] = $new_sessid;   这句注释掉。
2.            $this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid)));
变成
$this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now), array('session_id' => $old_sessid)));

就是不让原来的session_id 被修改,永远使用原来的session_id, 只延长 last_activity 上次访问时间





smilecc123 发表于 2014-5-4 17:25:01

用原生session的飘过 。。

lining_ci 发表于 2015-12-9 17:24:13

asdasd

lining_ci 发表于 2015-12-9 17:28:13

呵呵,都是逼的呀。。。
页: [1]
查看完整版本: CI 数据库SESSION失效问题的解决方法