之前写过两篇文章《自定义SESSION(二)——数据库保存》和《我为什么不使用session》 但后来发现都有问题。前者处理在实际中几乎没什么用处,而且session回收还得自己另外处理。后者频繁的操作数据库,打来了很大的性能问题。 这两天仔细考虑下,大致给出一个方案,但还没有具体详细的测试。 1、session处理和统计结合起来。同时游客也都有记录。 2、完全使用数据库和cookie来模拟session的功能。 3、用户的对session的操作都尽量保证在一条sql语句完成。不用到session的时候,绝对不多一条查询。 4、为了效率起见,session的回收没有集成进来,但提供了接口,可以调用实现。 暂时给出代码,不具体解释。 sql CREATETABLE*****_session (
sid char(32)NOTNULL,
uid int(10)NOTNULL,
username char(32)NOTNULL,
usertype tinyint(1)NOTNULL,
activetime int(10)NOTNULL,
expiry int(10)NOTNULL,
ip char(15)NOTNULL,
url char(80)NOTNULL,
value char(255)NOTNULL, PRIMARYKEY(sid ) )ENGINE=MEMORYDEFAULTCHARSET=utf8; php代码 <? classsession{ private$_sessionPrex='';//session的前缀 private$_time='';//当前时间 private$_model=null;//数据库操作模型 private$_expiry=1200;//session有效时间 private$_domain='';//session的作用域 protected$isNew=0;//判定操作动作0更新1增加 protected$session=array();//对应的一条session记录 publicfunctionconstruct($options){ $this->_setOptions($options); if(empty($this->_time))$this->_time=time(); $this->session['activetime']=$this->_time; } publicfunctionstart(){ $this->_getSid(); } publicfunctionset($key,$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); } $this->session[$key]=$value; }else{ $other=$this->session['value']; $other[$key]=$value; $this->session['value']=$other; } } publicfunctionget($key){ if(in_array($key,'expiry'))){ return$this->session[$key]; }else{ if(isset($this->session['value'][$key])){ return$this->session['value'][$key]; } returnnull; } } publicfunctiongc($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); } } publicfunctiondestroy(){ $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->_expiry); $this->_setCookie($this->_sessionPrex.'_uid',$this->_expiry); } publicfunctiondestruct(){ $this->_save(); } privatefunction_save(){ $dbSession=$this->session; $dbSession['value']=serialize($dbSession['value']); if(strlen($dbSession['value'])>255)$this->_error('session->valueistoolong!'); if($this->isNew==1){ //增加 $this->_model->insert($dbSession); }else{ //更新 $sid=$dbSession['sid']; $this->_model->update(array_slice($dbSession,1),'sid=''.$sid.'''); } } privatefunction_getSession($sid){ $dbSession=$this->_model->detail('sid=''.$sid.'''); if(!$dbSession)returnfalse; $dbSession['value']=unserialize($dbSession['value']); $this->session=array_merge($dbSession,$this->session); returntrue; } privatefunction_getSid(){ $sid=strip_tags($_COOKIE[$this->_sessionPrex.'_sid']); if(strlen($sid)==32){ if($this->_getSession($sid)){ returntrue; } }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; } privatefunction_setCookie($name,$value,$expiry=0){ if(empty($expiry))$expiry=$this->_expiry; if(empty($this->_domain)){ setcookie($name,$this->_time+$expiry,'/'); }else{ setcookie($name,'/',$this->_domain); } } privatefunction_getip(){ returngetip(); } privatefunction_setOptions($options){ foreach($optionsas$key=>$value){ if(inarray($key,array('sessionPrex','time','model','expiry','domain'))){ $key=''.$key; $this->$key=$value; } } } privatefunction_error($msg){ thrownewPhpbean_Exception($msg); } } ?> (注意,该代码不能直接使用,本文主要是提供一种思路) (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|