RE: [2.1.0]骑兵系列三:支持Memcached的Session类库
有个问题想请教各位:我按下载文件中的路径替换掉了CI中的代码,为什么获取不到指定的session?当我注释掉MY_session.php文件中的new Cache_Session_Handler;代码后就可以获取到指定的session了。当前的config配置如下:
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie'] = FALSE;
$config['sess_use_database'] = TRUE;
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = TRUE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update'] = 300;
昨天细看了一下代码,发现该session没有与数据库结合,所以今天研究了一下,特地将该功能补充了进去,如果有不正确的地方,还望各位指正,MY_session.php的代码如下:
<?phpif ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Native Session using Memcached
*
* Another session library extension that uses Native PHP session
* instead of the original Codeigniter cookie-based way.
* It also takes memcached as the session data storage, which will
* boost the performance of your app.
*
* @package CodeIgniter
* @subpackage Libraries
* @category Libraries
* @author Situo Dev Team <hello@situos.com>
* @license The MIT license
* @filesource
*/
// ------------------------------------------------------------------------
// Set session configs...
//new Cache_Session_Handler;#注释了该行代码,因为开启该行代码后无法获取session
session_start();
class MY_Session extends CI_Session {
/**
* Session Constructor
* session构造函数
*
* The constructor runs the session routines automatically
* whenever the class is instantiated.
*
* @access public
* @return void
*/
public function __construct($params = array())
{
parent::__construct($params);
}
// --------------------------------------------------------------------
/**
* Fetch the current session data if it exists
* 如果存在则获取当前session数据,即读取session数据
*
* @access public
* @return bool
*/
public function sess_read()
{
// Fetch the cookie
//获取Cookie信息
$session = $_SESSION;
// Is the session data we unserialized an array with the correct format?
// 未序列化的session数据是否为数组并且格式正确
if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity']))
{ //没有session时则返回False并清空session
log_message('debug', 'A session was not found.');
$this->sess_destroy(FALSE);
return FALSE;
}
// Is the session current?
// 是否为当前session
if (($session['last_activity'] + $this->sess_expiration) < $this->now)
{ //如果session有效期已过则清空session
$this->sess_destroy(FALSE);
return FALSE;
}
// Does the IP Match?
// 匹配IP地址是否正确
if ($this->sess_match_ip == TRUE AND $session['ip_address'] != $this->CI->input->ip_address())
{ //如果IP地址不匹配则清空session
$this->sess_destroy(FALSE);
return FALSE;
}
// Does the User Agent Match?
// 是否匹配浏览器
if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 120)))
{ //如果不是当前浏览器测清空session
$this->sess_destroy(FALSE);
return FALSE;
}
// Is there a corresponding session in the DB?
// 是否采用数据库存放session
if ($this->sess_use_database === TRUE)
{
$this->CI->db->where('session_id', $session['session_id']);
if ($this->sess_match_ip == TRUE)
{
$this->CI->db->where('ip_address', $session['ip_address']);
}
if ($this->sess_match_useragent == TRUE)
{
$this->CI->db->where('user_agent', $session['user_agent']);
}
$query = $this->CI->db->get($this->sess_table_name);
// No result?Kill it!
// 没有数据则清空session
if ($query->num_rows() == 0)
{
$this->sess_destroy(FALSE);
return FALSE;
}
// Is there custom data?If so, add it to the main session array
$row = $query->row();
if (isset($row->user_data) AND $row->user_data != '')
{
$custom_data = $this->_unserialize($row->user_data);
if (is_array($custom_data))
{
foreach ($custom_data as $key => $val)
{
$session[$key] = $val;
}
}
}
}
// Session is valid!
// 有效session数据
$this->userdata = $session;
unset($session);
return TRUE;
}
// --------------------------------------------------------------------
/**
* Write the session data
* 写入session数据
*
* @access public
* @return void
*/
public function sess_write()
{
// set the custom userdata, the session data we will set in a second
// 将session数据写入到原生的session全局变量中
$_SESSION = array();
foreach($this->userdata as $key => $val)
{
$_SESSION[$key] = $val;
}
//判断是否需要进行数据库操作
if($this->sess_use_database === TRUE)
{
$custom_userdata = $this->userdata;
foreach( array('session_id','ip_address','user_agent','last_activity') as $value )
{
unset($custom_userdata[$value]);
}
// Did we find any custom data?If not, we turn the empty array into a string
// since there's no reason to serialize and store an empty array in the DB
if(count($custom_userdata) === 0)
{
$custom_userdata = '';
}
else
{
// Serialize the custom data array so we can store it
$custom_userdata = $this->_serialize($custom_userdata);
}
// Run the update query
$this->CI->db->where('session_id', $this->userdata['session_id']);
// Update data
$data = array(
'last_activity' => $this->userdata['last_activity'],
'user_data' => $custom_userdata
);
$this->CI->db->update($this->sess_table_name, $data);
}
}
// --------------------------------------------------------------------
/**
* Create a new session
* 创建session
*
* @access public
* @return void
*/
public function sess_create()
{
if(session_id() == '')
{
session_start();
}
$_SESSION['session_id'] = session_id();
$_SESSION['ip_address'] = $this->CI->input->ip_address();
$_SESSION['user_agent'] = substr($this->CI->input->user_agent(), 0, 120);
$_SESSION['last_activity'] = $this->now;
$this->userdata = $_SESSION;
// Save the data to the DB if needed
if ($this->sess_use_database === TRUE)
{
//保存session数据
$this->CI->db->query($this->CI->db->insert_string($this->sess_table_name, $this->userdata));
}
}
// --------------------------------------------------------------------
/**
* Update an existing session
* 更新已存在的session数据
*
* @access public
* @return void
*/
public function sess_update()
{
// We only update the session every five minutes by default
// 默认session五分钟更新一次
if(($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)
{
return;
}
// Save the old session id so we know which record to
// update in the database if we need it
$old_sessid = $this->userdata['session_id'];
// Regenerate session id
// 重复注册sessionID
session_regenerate_id();
// Update the session data in the session data array
// 更新session数据中的session数据
$this->userdata['session_id'] = session_id();
$this->userdata['last_activity'] = $this->now;
// Update the session ID and last_activity field in the DB if needed
if ($this->sess_use_database === TRUE)
{
$this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $this->userdata['session_id']), array('session_id' => $old_sessid)));
}
}
// --------------------------------------------------------------------
/**
* Destroy the current session
* 清空当前session数据
*
* @access public
* @param bool 是否删除所有session数据
* @return void
*/
public function sess_destroy($destroy = TRUE)
{
// Kill the session DB row
if ($this->sess_use_database === TRUE AND isset($this->userdata['session_id']))
{
$this->CI->db->where('session_id', $this->userdata['session_id']);
$this->CI->db->delete($this->sess_table_name);
}
session_unset();
session_regenerate_id();
if($destroy)
{
session_destroy();
}
}
// --------------------------------------------------------------------
/**
* Does nothing for native sessions
* 对原生session不做任务处理
*
* @access public
* @return void
*/
//public function _sess_gc(){}
// --------------------------------------------------------------------
}
/* End of file MY_session.php */
/* Location: ./application/libraries/MY_session.php */
注://new Cache_Session_Handler;这行的代码被我注释了,因为如果开启该行代码后,无法获取session了。