session
在开发web应用中可谓是相当重要,php为session
提供了三种存储方式:文件、内存、自定义存储,默认是使用文件存储。
这里我们通过php提供的session_set_save_handler()
函数来重写session
,从而将session存储到数据库中。
注释:
session_set_save_handler()
设置用户自定义 会话存储函数。 如果想使用 PHP 内置的会话存储机制之外的方式, 可以使用本函数。 例如,可以自定义会话存储函数来将会话数据存储到数据库。
PHP5.4以后支持了SessionHandlerInterface接口。
SessionHandlerInterface {
/* 抽象方法 */
abstract public bool close ( void )
abstract public bool destroy ( string $session_id )
abstract public bool gc ( int $maxlifetime )
abstract public bool open ( string $save_path , string $name )
abstract public string read ( string $session_id )
abstract public bool write ( string $session_id , string $session_data )
}
我们需要做的就是实现这个接口里所有的方法,然后通过session_set_save_hander()
函数来使方法生效。
class Session_Handler_To_DB implements SessionHandlerInterface{
//会话生命周期
protected $_lifetime='7200';
//session table
protected $_table='';
/**
* 构造函数
* @param arrSettings array 配置参数[可选]
*/
function __construct($arrSettings=array()){
if(is_numeric($arrSettings['lifetime'])) $this->_lifetime=$arrSettings['lifetime'];
}
/**
* SESSION打开
* @param save_path string 保存路径
* @param session_name string 会话id
* @return boolean 是否成功
*/
public function open($savePath, $sessionName){
return true;
}
/**
* SESSION关闭
* @return boolean
*/
public function close(){
return true;
}
/**
* 读取SESSION信息并验证是否有效
* @param key string session的key值
* @return mixed
*/
public function read($key){
try {
$db = GetDB();
$current_time = time();
/* 首先删除当前key下已经过期的session*/
//$db->Query('DELETE FROM '.$this->_table.' WHERE SESS_KEY=? AND EXPIRY_DATE<?', array($key, $current_time));
/*查询当前key下未超时的Session*/
$query = $db->Query("SELECT SESS_VALUE FROM ".$this->_table.' WHERE SESS_KEY=? AND EXPIRY_DATE >=?', array($key, $current_time));
/*返回结果SESS_VALUE*/
if(is_array($query) && count($query)>0){
return $query[0]['SESS_VALUE'];
}else return false;
} catch (CO_DB_Exception $e) {
//接收数据库异常
return false;
}
}
/**
* 写入SESSION信息
* @param key string session的key值
* @param val string session数值
* @return boolean
*/
public function write($key, $val){
try {
$db = GetDB();
//获取远程操作IP
$ip = bindec(decbin(ip2long($_SERVER['REMOTE_ADDR'])));
$current_time = time();
/* 刷新过期时间,并插入session记录*/
$new_expriy = $current_time + $this->_lifetime;
if($db->Select($this->_table, array('SESS_KEY' => $key), array('select'=>array(SESS_KEY))) === false){
$ins = $db->Insert($this->_table, array(
"SESS_KEY"=>$key,
"SESS_VALUE"=>$val,
"EXPIRY_DATE"=>$new_expriy,
"LOGIN_IP"=>$ip
));
}else{
//如果session已经存在,只更新过期时间
$ins = $db->Query('UPDATE '.$this->_table.' SET `EXPIRY_DATE`=?, `SESS_VALUE`=?, `LOGIN_IP`=? WHERE `SESS_KEY`=?', array($new_expriy, $val, $ip, $key));
}
return $ins===false?false:true;
} catch (Exception $e) {
//接收数据库异常
return false;
}
}
/**
* 删除Session信息
* @param key string Session的key值
* @return boolean
*/
public function destroy($key){
try {
$db=GetDB();
$db->Delete($this->_table, array('SESS_KEY'=>$key));
return true;
} catch (Exception $e) {
//接收数据库异常
return false;
}
}
/**
* 回收超时SESSION信息
* @param
* @return boolean
*/
public function gc($maxlifetime){
try {
$db=GetDB();
$db->Query('DELETE FROM '.$this->_table.' WHERE `EXPIRY_DATE`<?', array(time()));
} catch (Exception $e) {
//接收数据库异常
}
return true;
}
}