I have written two articles before, "Customized SESSION (2) - Database Saving" and "Why I Don't Use Session"
But later I found problems with both. The former processing is almost useless in practice, and session recycling has to be handled separately. The latter frequently operates the database, causing big performance problems.
After careful consideration in the past two days, I have roughly given a plan, but there is no specific and detailed test.
1. Combine session processing and statistics. Visitors are also recorded.
2. Completely use database and cookies to simulate session functions.
3. The user’s operations on the session should be completed in one SQL statement as much as possible. When the session is not needed, there is absolutely no more than one query.
4. For the sake of efficiency, session recycling is not integrated, but an interface is provided and can be called to implement it.
The code is given temporarily without detailed explanation.
sql
CREATE TABLE `*****_session` (
`sid` char(32) NOT NULL,
`uid` int(10) NOT NULL,
`username` char(32) NOT NULL,
`usertype` tinyint(1) NOT NULL,
`activetime` int(10) NOT NULL,
`expiry` int( 10) NOT NULL,
`ip` char(15) NOT NULL,
`url` char(80) NOT NULL,
`value` char(255) NOT NULL,
PRIMARY KEY ( `sid`)
) ENGINE=MEMORY DEFAULT CHARSET=utf8;
php code
class session{
private $_sessionPrex= '';//session prefix
private $_time = '';//current time
private $_model = null;//database operation model
private $_expiry = 1200;//session validity time
private $_domain = '';//session scope
protected $isNew = 0;// Determine operation action 0 Update 1 Added
protected $session = array();//Corresponding session record
public function __construct($options){
$this-> _setOptions($options);
If(empty($this->_time))$this->_time = time();
$this->session['activetime'] = $this- >_time; value){
if(in_array($key,array('uid','username','usertype','url','expiry'))){
if($key == 'expiry' ){
$this->_setCookie($this->_sessionPrex.'_sid',$this->session['sid'],$value);
$this->_setCookie($ this->_sessionPrex.'_uid',$this->session['uid'],$value);
}else{
$other = $this->session['value'];
$other[$key] = $value;
$this->session['value'] = $ other;
} }
}
public function get($key){
',' Expiry '))))) {
Return $ this-& gt; session [$ key];
} else {
if (ISSET ($ this- & gt; session [' value '] [$ key])){
return $this->session['value'][$key];
return null;
} }
public function gc($file,$time = 1200){
$lasttime = file_get_contents($file);
if($lasttime + $time<$this->_time){
file_put_contents($file,$this->_time);
return $this->_model->delete('activetime+expiry<'.$this->_time);
}
}
public function destroy(){
$this->session['uid'] = 0;
$this->session['username'] = '';
$this->session['usertype'] = -1;
$this->session['expiry'] = $this->_expiry;
$this->session['value'] = array();
$this->_setCookie($this->_sessionPrex.'_sid',$this->session['sid'],$this->_expiry);
$this->_setCookie($this->_sessionPrex.'_uid',$this->session['uid'],$this->_expiry);
}
public function __destruct(){
$this->_save();
}
private function _save(){
$dbSession = $this->session;
$dbSession['value'] = serialize($dbSession['value']);
if(strlen($dbSession['value'])>255)$this->_error('session->value is too long!');
if($this->isNew == 1){
//增加
$this->_model->insert($dbSession);
}else{
//更新
$sid = $dbSession['sid'];
$this->_model->update(array_slice($dbSession,1),'sid=''.$sid.''');
}
}
private function _getSession($sid){
$dbSession = $this->_model->detail('sid = ''.$sid.''');
if(!$dbSession)return false;
$dbSession['value'] = unserialize($dbSession['value']);
$this->session = array_merge($dbSession,$this->session);
return true;
}
private function _getSid(){
$sid = strip_tags($_COOKIE[$this->_sessionPrex.'_sid']);
if(strlen($sid)==32){
if($this->_getSession($sid)){
return true;
}
}else{
$sid = md5(time().mt_rand(1000,10000));
$this->_setCookie($this->_sessionPrex.'_sid',$sid);
}
$this->_setCookie($this->_sessionPrex.'_uid',0);
$this->session = array(
'uid' => 0,
'username' => '',
'usertype' => -1,
'activetime' => $this->_time,
'ip' => $this->_getip(),
'url' => strip_tags($_SERVER['REQUEST_URI']),
'expiry' =>$this->_expiry,
'value' => array()
);
$this->isNew = 1;
$this->session['sid'] = $sid;
}
private function _setCookie($name,$value,$expiry=0){
if(empty($expiry))$expiry = $this->_expiry;
if(empty($this->_domain)){
setcookie($name,$value,$this->_time + $expiry,'/');
}else{
setcookie($name,$value,$this->_time + $expiry,'/',$this->_domain);
}
}
private function _getip(){
return getip();
}
private function _setOptions($options){
foreach ($options as $key=>$value){
if(in_array($key,array('sessionPrex','time','model','expiry','domain'))){
$key = '_'.$key;
$this->$key = $value;
}
}
}
private function _error($msg){
throw new Phpbean_Exception($msg);
}
}
?>
(注意,该代码不能直接使用,本文主要是提供一种思路)