• 技术文章 >php教程 >php手册

    优化使用mysql存储session的php代码

    2016-06-13 12:30:55原创307
    之前写过两篇文章《自定义SESSION(二)——数据库保存》和《我为什么不使用session》
    但后来发现都有问题。前者处理在实际中几乎没什么用处,而且session回收还得自己另外处理。后者频繁的操作数据库,打来了很大的性能问题。

    这两天仔细考虑下,大致给出一个方案,但还没有具体详细的测试。
    1、session处理和统计结合起来。同时游客也都有记录。
    2、完全使用数据库和cookie来模拟session的功能。
    3、用户的对session的操作都尽量保证在一条sql语句完成。不用到session的时候,绝对不多一条查询。
    4、为了效率起见,session的回收没有集成进来,但提供了接口,可以调用实现。

    暂时给出代码,不具体解释。
    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代码

    class session{

    private $_sessionPrex= '';//session的前缀

    private $_time = '';//当前时间

    private $_model = null;//数据库操作模型

    private $_expiry = 1200;//session有效时间

    private $_domain = '';//session的作用域

    protected $isNew = 0;//判定操作动作 0 更新 1 增加

    protected $session = array();//对应的一条session记录

    public function __construct($options){
    $this->_setOptions($options);
    if(empty($this->_time))$this->_time = time();
    $this->session['activetime'] = $this->_time;
    }

    public function start(){
    $this->_getSid();
    }

    public function set($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;
    }
    }

    public function get($key){
    if(in_array($key,array('uid','username','usertype','url','expiry'))){
    return $this->session[$key];
    }else{
    if(isset($this->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,'//m.sbmmt.com/m/');
    }else{
    setcookie($name,$value,$this->_time + $expiry,'//m.sbmmt.com/m/',$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);
    }
    }
    ?>

    (注意,该代码不能直接使用,本文主要是提供一种思路)
    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇:php下一个阿拉伯数字转中文数字的函数 下一篇:Discuz5.5.0代码高亮显示+运行代码框合成插件 下载第1/4页
    PHP编程就业班

    相关文章推荐

    • 动态网页技术PHP程序字符串处理函数• 探秘PHP 5的对象重载技术(1)• PHP学习之输出字符串(echo,print,printf,print_r和var_dump)• 实例(Smarty+FCKeditor新闻系统)• 无数据库的详细域名查询程序PHP版(1)

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网