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

之前写过两篇文章《自定义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,'/'); 
        }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); 
    } 

?>

(注意,该代码不能直接使用,本文主要是提供一种思路)

(0)

相关推荐

  • php+mysql查询优化简单实例

    本文实例分析了php+mysql查询优化的方法.分享给大家供大家参考.具体分析如下: PHP+Mysql是一个最经常使用的黄金搭档,它们俩配合使用,能够发挥出最佳性能,当然,如果配合Apache使用,就更加Perfect了. 因此,需要做好对mysql的查询优化,下面通过一个简单的例子,展现不同的SQL语句对于查询速度的影响. 存在这样的一张表test,它有一个自增的id作为主索引,现在要查询id号处于某一个范围内的记录,可以使用如下SQL语句: 复制代码 代码如下: SELECT * FROM

  • php导入大量数据到mysql性能优化技巧

    本文实例讲述了php导入大量数据到mysql性能优化技巧.分享给大家供大家参考.具体分析如下: 在mysql中我们结合php把一些文件导入到mysql中,这里就来分享一下我对15000条记录进行导入时分析与优化,需要的朋友可以参考一下. 之前有几篇文章,说了最近tiandi在帮朋友做一个小项目,用于统计电话号码的,每次按需求从数据库里随机生成打包的电话号码,然后不停地让人打这些电话号码推销产品(小小鄙视一下这样的行为).但是朋友要求帮忙,咱也不能不帮啊,是吧.程序两个星期前已经做好,测试完毕交工

  • PHP执行速率优化技巧小结

    1.在可以用file_get_contents替代file.fopen.feof.fgets等系列方法的情况下,尽量用file_get_contents,因为他的效率高得多!但是要注意file_get_contents在打开一个URL文件时候的PHP版本问题: 2.尽量的少进行文件操作,虽然PHP的文件操作效率也不低的: 3.优化SELECT SQL语句,在可能的情况下尽量少的进行INSERT.UPDATE操作(在UPDATE上,我被恶批过): 4.尽可能的使用PHP内部函数(但是我却为了找个P

  • LAMP服务器性能优化技巧之加速PHP

    Apache服务器优化.PHP优化.Mysql优化 1.使用eaccelerator 我们上面的介绍Apache服务器的优化,如果您曾经浏览过 PHP 的网页时,或许会发现:怎么 PHP 的速度慢慢的,这是怎么一回事啊?PHP 不是号称速度上面的反应是很快速的吗?怎么会慢慢的呢?这是由于 PHP 的程序代码去调用了太多的函式库,而这些函式库每次调用都需要由硬盘读出来,有没有办法提升 PHP 的执行速度啊.如果我们可以将这些在硬盘里面的函式库先读到高速缓存中( Cache ),由于内存的速度可比硬

  • php程序效率优化的一些策略小结

    1.在可以用file_get_contents替代file.fopen.feof.fgets等系列方法的情况下,尽量用 file_get_contents,因为他的效率高得多!但是要注意file_get_contents在打开一个URL文件时候的PHP版本问题; 2.尽量的少进行文件操作,虽然PHP的文件操作效率也不低的; 3.优化Select SQL语句,在可能的情况下尽量少的进行Insert.Update操作(在update上,我被恶批过); 4.尽可能的使用PHP内部函数(但是我却为了找个

  • php mssql 分页SQL语句优化 持续影响

    复制代码 代码如下: <?php /** * @Filename :page.sql.class.php * @CreatTime :2009-01-06 * @Descrition :此类为SQL语句处理类. * @UpdateTime-1 :null * @Version :jswweb1.0.0 * @Author :fkedwgwy * @Dome : $sql//SQL语句 $allcount//总记录数 $pagesize//页面显示记录条数 $page//当前页 $sqlc= ne

  • php下MYSQL limit的优化

    同样是取10条数据 select * from yanxue8_visit limit 10000,10 和select * from yanxue8_visit limit 0,10 就不是一个数量级别的. 网上也很多关于limit的五条优化准则,都是翻译自mysql手册,虽然正确但不实用.今天发现一篇文章写了些关于limit优化的,很不错.原文地址:http://www.zhenhua.org/article.asp?id=200 文中不是直接使用limit,而是首先获取到offset的id

  • 50个PHP程序性能优化的方法

    1. 用单引号代替双引号来包含字符串,这样做会更快一些.因为 PHP 会在双引号包围的 字符串中搜寻变量,单引号则不会,注意:只有 echo 能这么做,它是一种可以把多个字符 串当作参数的"函数"(译注:PHP 手册中说 echo 是语言结构,不是真正的函数,故把函数 加上了双引号). 2.如果能将类的方法定义成 static,就尽量定义成 static,它的速度会提升将近 4 倍. 3.$row['id'] 的速度是$row[id]的 7 倍. 4.echo 比 print 快,并且

  • PHP数据库编程之MySQL优化策略概述

    本文简单讲述了PHP数据库编程之MySQL优化策略.分享给大家供大家参考,具体如下: 前些天看到一篇文章说到PHP的瓶颈很多情况下不在PHP自身,而在于数据库.我们都知道,PHP开发中,数据的增删改查是核心.为了提升PHP的运行效率,程序员不光需要写出逻辑清晰,效率很高的代码,还要能对query语句进行优化.虽然我们对数据库的读取写入速度上却是无能为力,但在一些数据库类扩展像memcache.mongodb.redis这样的数据存储服务器的帮助下,PHP也能达到更快的存取速度,所以了解学习这些扩

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

    之前写过两篇文章<自定义SESSION(二)--数据库保存>和<我为什么不使用session>   但后来发现都有问题.前者处理在实际中几乎没什么用处,而且session回收还得自己另外处理.后者频繁的操作数据库,打来了很大的性能问题. 这两天仔细考虑下,大致给出一个方案,但还没有具体详细的测试.   1.session处理和统计结合起来.同时游客也都有记录.   2.完全使用数据库和cookie来模拟session的功能.   3.用户的对session的操作都尽量保证在一条sq

  • PHP利用MySQL保存session的实现思路及示例代码

    实现环境: PHP 5.4.24 MySQL 5.6.19 OS X 10.9.4/Apache 2.2.26 一.代码 CREATE TABLE `session` ( `skey` char(32) CHARACTER SET ascii NOT NULL, `data` text COLLATE utf8mb4_bin, `expire` int(11) NOT NULL, PRIMARY KEY (`skey`), KEY `index_session_expire` (`expire`

  • PHP使用Redis替代文件存储Session的方法

    本文实例讲述了PHP使用Redis替代文件存储Session的方法.分享给大家供大家参考,具体如下: PHP默认使用文件存储session,如果并发量大,效率非常低.而Redis对高并发的支持非常好,所以,可以使用redis替代文件存储session. 这里,介绍下php的session_set_save_handler 函数的作用和使用方法.该函数定义用户级session保存函数(如打开.关闭.写入等). 原型如下: bool session_set_save_hanler(callback

  • 基于Mysql存储引擎的深入分析

    MySQL有很多种存储引擎,针对不同的应用,可以为每张表选择合适的存储引擎,这样有助于提升MySQL性能.创建新闻表news: 复制代码 代码如下: CREATE  TABLE `sandbox`.`news` (      `id` INT NOT NULL AUTO_INCREMENT ,      `name` VARCHAR(45) NULL ,          `content` VARCHAR(45) NULL ,      `created` VARCHAR(45) NULL ,

  • PHP实现利用MySQL保存session的方法

    session是PHP程序设计中服务器端用来保存用户信息的一个变量,具有非常广泛的应用价值.本文实例讲述了PHP实现利用MySQL保存session的方法.分享给大家供大家参考之用.具体步骤如下: 本文实例的实现环境为: PHP 5.4.24 MySQL 5.6.19 OS X 10.9.4/Apache 2.2.26 一.代码部分 1.SQL语句: CREATE TABLE `session` ( `skey` char(32) CHARACTER SET ascii NOT NULL, `d

  • mysql事务处理用法与实例代码详解

    MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关 1.MyISAM:不支持事务,用于只读程序提高性能 2.InnoDB:支持ACID事务.行级锁.并发 3.Berkeley DB:支持事务 一个事务是一个连续的一组数据库操作,就好像它是一个单一的工作单元进行.换言之,永远不会是完整的事务,除非该组内的每个单独的操作是成功的.如果在事务的任何操作失败,则整个事务将失败. 实际上,会俱乐部许多SQL查询到一个组中,将执行所有的人都一起作为事务的一部分. 事务的特性: 事务有以下

  • PHP中如何使用Redis接管文件存储Session详解

    前言 php默认使用文件存储session,如果并发量大,效率会非常低.而redis对高并发的支持非常好,可以利用redis替换文件来存储session. 最近就遇到了这个问题,之前找了网上的一套直播系统给客户用,刚开始是没问题的,在后面人数上来之后网站开始变得卡顿,卡的一批.之后查看php慢日志发现session_start()的身影,好吧,原来是万恶的文件存储session,跟我之前进的坑一模一样--之前做的教务查询系统直接用的session没有用cookie,结果在高并发的情况下php原地

  • redis 替代php文件存储session的实例

    redis 替代php文件存储session的实例 查看实例之前请先了解   PHP session_set_save_handler函数的用法 定义个SessionManager  类 class SessionManager { private $redis; public function __construct(){ $this->redis = new Redis(); $this->redis->connect('192.168.0.102', 6379); $retval

  • 详解Asp.net Core 使用Redis存储Session

    前言 Asp.net Core 改变了之前的封闭,现在开源且开放,下面我们来用Redis存储Session来做一个简单的测试,或者叫做中间件(middleware). 对于Session来说褒贬不一,很多人直接说不要用,也有很多人在用,这个也没有绝对的这义,个人认为只要不影什么且又可以方便实现的东西是可以用的,现在不对可不可用做表态,我们只关心实现. 类库引用 这个相对于之前的.net是方便了不少,需要在project.json中的dependencies节点中添加如下内容: "StackExc

  • PHP+MySQL存储数据常见中文乱码问题小结

    本文实例总结了PHP+MySQL存储数据常见中文乱码问题.分享给大家供大家参考,具体如下: PHP+MySQL出现中文乱码的常见原因: 1. MYSQL数据库的编码是utf8,与PHP网页的编码格式不一致,就会造成MYSQL中的中文乱码. 2. 使用MYSQL中创建表.或者选择字段时设置的类型不是utf8,而网页编码不是utf8,也可能造成MYSQL中文乱码. 3. PHP页面的字符集与数据库的编码不一致. 4. PHP连接MYSQL数据库,操作是设定的语句指定的编码和页面编码,PHP页面编码不

随机推荐