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
- php之自定义session存储机制【3】
- 自定义session处理机制之数据库存储session
- php自定义session存储方式
- php会话机制之Session
- PHP中用户自定义Session处理机制
- php 实现自定义session存储方式
- session与cookie的比较:自定义session存储机制
- PHP之session机制和优化
- PHP函数源码之SESSION实现机制
- PHP之Session配置文件存储路径
- php的session机制以及自定义会话管理器
- 在PHP中自定义session的存储方式
- session存储和机制
- session的存储机制
- php中Session的生成机制、回收机制和存储机制探究
- php session机制
- PHP session回收机制
- PHP session回收机制
- <读书笔记>软件调试之道 :问题的核心-重现问题
- 诊断Java代码中常见的数据库性能热点问题应该这么做!
- Style input element to fill remaining width of its container
- Android杂记(3)FileUtils工具类梳理
- 欢迎使用CSDN-markdown编辑器
- php之自定义session存储机制【3】
- Keeloq解码软件实现
- typedefine 语法
- LeetCode 331. Verify Preorder Serialization of a Binary Tree(校验二叉树的前序遍历序列化)
- 使用Git上传本地代码到http://git.oschina.net/(SSH方式)
- Const
- 4月面试总结
- Ecplise打开xml文件时报Failed to create the part's controls错误
- 时间复杂度一定的算法1s内能处理的问题规模上限