php之自定义session存储机制【3】

来源:互联网 发布:彩八仙时时彩软件 编辑:程序博客网 时间:2024/05/17 09:17

session默认是以文件形式存储的,当网站的访问量很大的情况下,因为文件的IO性能问题,会让服务器的开销巨大,比较典型做法是把session存入数据库或内存,本文是以数据库为例。

主要有两个步骤:
1. 自定义实现session的操作方法,比如读、写、删除、垃圾回收…
2. 告诉系统的session机制调用自定义的方法去处理session.

数据库创建语句:

 CREATE TABLE `t_session` (  `sess_id` varchar(50) NOT NULL COMMENT 'session id',  `sess_content` text NOT NULL COMMENT 'session内容',  `last_write` int(10) unsigned NOT NULL COMMENT '最后写入时间',  PRIMARY KEY (`sess_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8

代码如下:
这里写图片描述
session_db.php

<?phprequire_once 'MyPdo.class.php';require_once 'ModelFactory.class.php';require_once 'SessionModel.class.php';// function __autoload($class){//     $filename = $class.".class.php";//     if(file_exists($filename)){//         require_once $filename;//     }// }//让系统的session机制调用自定义的方法去处理session.session_set_save_handler('sessionOpen', 'sessionClose', 'sessionRead', 'sessionWrite', 'sessionDestroy', 'sessionGc');//打开sessionfunction sessionOpen(){    echo "<br>sessionOpen";}//关闭sessionfunction sessionClose(){    echo "<br>sessionClose";    return true;}//session根据id读取数据function sessionRead($sess_id){    echo "<br>sessionRead";    $model = ModelFactory::M("SessionModel");    return $model->read($sess_id);}//session根据id写入数据function sessionWrite($sess_id,$content){    echo "<br>sessionWrite";    $model = ModelFactory::M("SessionModel");    $model->write($sess_id,$content);}/** * 销毁session,调用session_destroy()触发 * @param string $sess_id */function sessionDestroy($sess_id){    echo "<br>sessionDestroy";    $model = ModelFactory::M("SessionModel");    $model->destroy($sess_id);}//垃圾session数据回收function sessionGc($lifetime){    echo "<br>sessionGc";    $model = ModelFactory::M("SessionModel");    $model->gc($lifetime);}?>

MyPdo.class.php

<?phpclass MyPdo{    private static $_instance = null;    private $dbh;    private function __construct($config)    {        $dsn = "mysql:host={$config['host']}; port={$config['port']}; dbname={$config['dbname']}";        $options = array(            PDO::MYSQL_ATTR_INIT_COMMAND => "set names {$config['charset']}"        );        try {            $this->dbh = new PDO($dsn, $config['username'], $config['passwd'], $options);        } catch (PDOException $e) {            echo 'Connection failed: ' . $e->getMessage();        }        $this->dbh -> setAttribute ( PDO :: ATTR_ERRMODE ,  PDO :: ERRMODE_EXCEPTION );    }    private function __clone()    {}    public static function getInstance($config = array('host'=>'localhost','port'=>'3306','dbname'=>'db7','charset'=>'utf8','username'=>'root',"passwd"=>'root'))    {        return isset(self::$_instance) ? self::$_instance : (self::$_instance = new self($config));    }    public function getPdo(){        return $this->dbh;    }    public function close() {       $this->dbh = null;       self::$_instance = null;    }    public function query($sql) {        try {           $stmt =  $this->dbh->query($sql);           return $stmt;        } catch (PDOException $e) {            echo "<p>sql语句执行失败,请参考如下信息:</p>";            echo "<br>错误文件:" .$e->getFile();            echo "<br>错误行号:" .$e->getLine();            echo "<br>错误代号:" .$e->getCode();             echo "<br>错误信息:" .$e->getMessage();            echo "<br>错误语句:" .$sql;        }    }    public function exec($sql) {     try {           $num =  $this->dbh->exec($sql);//失败返回false,成功返回受影响的行数,也可能是0           if($num >= 0){               return true;           }           return $num;        } catch (PDOException $e) {            echo "<p>sql语句执行失败,请参考如下信息:</p>";            echo "<br>错误文件:" .$e->getFile();            echo "<br>错误行号:" .$e->getLine();            echo "<br>错误代号:" .$e->getCode();             echo "<br>错误信息:" .$e->getMessage();            echo "<br>错误语句:" .$sql;        }    }    /**     * 获取一行的结果     * @param string $sql     * @return array 数组     */    public function fetchRow($sql){        $stmt = $this->query($sql);        return $stmt->fetch(PDO::FETCH_ASSOC);    }    /**     * 获取多行结果     * @param unknown $sql     * @return array 二维数组     */    public function fetchAll($sql) {        $stmt = $this->query($sql);        return $stmt->fetchAll(PDO::FETCH_ASSOC);    }    /**     * 获取一个数据     * @param string $sql     * @return string     */    public function fetchData($sql) {        $stmt = $this->query($sql);        $result =  $stmt->fetch(PDO::FETCH_NUM);        if($result){            return $result[0];        }        return '';    }}?>

ModelFactory.class.php

<?phpclass ModelFactory{    private static $arr = array();    static function M($class) {        if(!array_key_exists($class, static::$arr)){            static::$arr[$class] = new $class();        }        return static::$arr[$class];    }}?>

SessionModel.class.php

<?phpclass SessionModel{  /**   * 写入session_id的内容   * @param string $sess_id   * @param string $content   */  public function write($sess_id,$content) {      $sql = "replace into t_session  (sess_id, sess_content, last_write) values ('$sess_id', '$content', UNIX_TIMESTAMP());";      return MyPdo::getInstance()->exec($sql);  }  /**   * 根据session_id读取内容   * @param string $sess_id   * @return string   */  public function read($sess_id) {      $sql = "select sess_content from  t_session where sess_id = '$sess_id'";      return MyPdo::getInstance()->fetchData($sql);  }  /**   * 销毁session_id数据   * @param string $sess_id   */  public function destroy($sess_id) {      $sql = "delete from t_session where sess_id = '$sess_id'";      return MyPdo::getInstance()->exec($sql);  }  /***   * gc垃圾回收删除超过有效期的session数据   * @param int $lifetime   * @return Ambigous <boolean, int>   */  public function gc($lifetime){      $sql = "delete from t_session where last_write < (UNIX_TIMESTAMP()- $lifetime)";      return MyPdo::getInstance()->exec($sql);  }}?>

use_session_db.php

<?phprequire 'session_db.php';//每2次访问服务器,可能进行1次垃圾扫描回收ini_set('session.gc_probability', '1');ini_set('session.gc_divisor', '2');//设置session的有效期10秒ini_set('session.gc_maxlifetime', '10');@session_start();echo '<br>current session id= '.session_id();echo '<br>';print_r($_SESSION);$_SESSION['name'] = 'jack';$_SESSION['age'] = 60;$_SESSION['city'] = 'guangzhou';$_SESSION['age'] = 88;// session_destroy();echo "<br>I am the last code!!";

这里写图片描述

session_destroy() 会触发sessionDestroy(),并且马上关闭session
这里写图片描述

1 0
原创粉丝点击