ThinkPHP自定义SESSION驱动之数据库存储
在ThinkPHP中,SESSION相关的数据库驱动已经给了,如果你下载的是ThinkPHP完整包的话,你应该在ThinkPHP目录下看到Extend目录,在此目录下,你应该会看到Driver/Session/SessionDb.class.php文件。这个就是ThinkPHP中数据库处理SESSION的驱动。
要在ThinkPHP中启用数据库处理SESSION,你应该在配置文件中写入如下配置:
//自定义SESSION处理
'SESSION_TYPE' => 'Db',
当然,你必须写入数据库的相关配置。
启用数据库存储SESSION后,就应该创建SESSION存储的表,创建的SQL语句在SessionDb.class.php文件的注释中,你只需后,稍作修整,执行一下就可以了,SQL语句如下(请自行更改表前缀):
CREATE TABLE ly_session (
session_id varchar(255) NOT NULL,
session_expire int(11) NOT NULL,
session_data blob,
UNIQUE KEY `session_id` (`session_id`)
);
定义SESSION的数据库驱动也就如此简单。
ThinkPHP自定义SESSION驱动之Redis
在书写Redis驱动之前,我们有必要大概的了解一下,自定义数据库驱动是如何实现的。
ThinkPHP中自定义SESSION处理的实现原理
打开ThinkPHP目录下的Common/function.php文件,查找session函数。你将看到如下代码:
/**
* session管理函数
* @param string|array $name session名称 如果为数组则表示进行session设置
* @param mixed $value session值
* @return mixed
*/
function session($name,$value='') {
$prefix = C('SESSION_PREFIX');
if(is_array($name)) { // session初始化 在session_start 之前调用
/** 些处省略2000字 **/
if(C('SESSION_TYPE')) { // 读取session驱动
$class = 'Session'. ucwords(strtolower(C('SESSION_TYPE')));
// 检查驱动类
if(require_cache(EXTEND_PATH.'Driver/Session/'.$class.'.class.php')) {
$hander = new $class();
$hander->execute();
}else {
// 类没有定义
throw_exception(L('_CLASS_NOT_EXIST_').': ' . $class);
}
}
// 启动session
if(C('SESSION_AUTO_START')) session_start();
}elseif('' === $value){
}else{
}
}elseif(is_null($value)){ // 删除session
}else{ // 设置session
}
}
从第13行代码开始看起:如果定义了"SESSION_TYPE"配置项(假设配置成了"Redis")的话,就会首先把这个配置项转化成小写,再让首字母转成大写后,再与Session连接,接着是载入ThinkPHP目录下的Extend/Driver/Session/SessionRedis.class.php文件;载入成功之后,便是实例化,然后调用execute方法。
下面,我列出了ThinkPHP中,数据库处理的Session的驱动文件,代码如下(只列出了结构):
<?php
defined('THINK_PATH') or exit();
/**
* 数据库方式Session驱动
* @category Extend
* @package Extend
* @subpackage Driver.Session
* @author liu21st <liu21st@gmail.com>
*/
class SessionDb {
/**
* Session有效时间
*/
protected $lifeTime = '';
/**
* session保存的数据库名
*/
protected $sessionTable = '';
/**
* 数据库句柄
*/
protected $hander = array();
/**
* 打开Session
* @access public
* @param string $savePath
* @param mixed $sessName
*/
public function open($savePath, $sessName) {
}
/**
* 关闭Session
* @access public
*/
public function close() {
}
/**
* 读取Session
* @access public
* @param string $sessID
*/
public function read($sessID) {
}
/**
* 写入Session
* @access public
* @param string $sessID
* @param String $sessData
*/
public function write($sessID,$sessData) {
}
/**
* 删除Session
* @access public
* @param string $sessID
*/
public function destroy($sessID) {
}
/**
* Session 垃圾回收
* @access public
* @param string $sessMaxLifeTime
*/
public function gc($sessMaxLifeTime) {
}
/**
* 打开Session
* @access public
*/
public function execute() {
session_set_save_handler(array(&$this,"open"),
array(&$this,"close"),
array(&$this,"read"),
array(&$this,"write"),
array(&$this,"destroy"),
array(&$this,"gc"));
}
}
说了那么多,现在开始实战吧!
定义配置文件
在你的配置文件中入如下的配置!
//自定议SESSION处理
'SESSION_TYPE' => 'Redis',
//Redis服务器地址
'REDIS_HOST' => '127.0.0.1',
//Redis服务器端口
'REDIS_PORT' => 6379,
书写Redis驱动
在ThinkPHP目录下的Extend/Driver/Session目录下,新建一个SessionRedis.Class.php文件。然后把以上数据库驱动代码进来填空即可(修改部分,并注意一下返回值什么的就行了)。最终代码如下:
<?php
/**
* Description: 自定义ThinkPHP中Redis驱动
* Site: http://www.lyblog.net
*/
defined('THINK_PATH') or exit();
/**
* Redis方式Session驱动
* @category Extend
* @package Extend
* @subpackage Driver.Session
* @author liu21st <liu21st@gmail.com>
*/
class SessionRedis {
/**
* Session有效时间
*/
protected $lifeTime = '';
/**
* 保存Redis连接对象
*/
protected $redis = '';
/**
* 打开Session
* @access public
* @param string $savePath
* @param mixed $sessName
*/
public function open($savePath, $sessName) {
$this->lifeTime = C('SESSION_EXPIRE') ? C('SESSION_EXPIRE') : ini_get('session.gc_maxlifetime');
$this->redis = new Redis();
return $this->redis->connect(C('REDIS_HOST'),C('REDIS_PORT'));
}
/**
* 关闭Session
* @access public
*/
public function close() {
return $this->redis->close();
}
/**
* 读取Session
* @access public
* @param string $sessID
*/
public function read($sessID) {
$sessID = C('SESSION_PREFIX').$sessID;
$data = $this->redis->get($sessID);
return $data ? $data : '';
}
/**
* 写入Session
* @access public
* @param string $sessID
* @param String $sessData
*/
public function write($sessID,$sessData) {
$sessID = C('SESSION_PREFIX').$sessID;
return $this->redis->set($sessID, $sessData, $this->lifeTime);
}
/**
* 删除Session
* @access public
* @param string $sessID
*/
public function destroy($sessID) {
$sessID = C('SESSION_PREFIX').$sessID;
return $this->redis->delete($sessID);
}
/**
* Session 垃圾回收
* @access public
* @param string $sessMaxLifeTime
*/
public function gc($sessMaxLifeTime) {
return true;
}
/**
* 打开Session
* @access public
*/
public function execute() {
session_set_save_handler(array(&$this,"open"),
array(&$this,"close"),
array(&$this,"read"),
array(&$this,"write"),
array(&$this,"destroy"),
array(&$this,"gc"));
}
}
扩展阅读
很多人以为只要这么写了,就可以直接使用了,其实不是这样了,你必须安装Redis服务。之前说过Linux下安装Redis安装及配置;你可以点阅“Ubuntu 下安装及配置php redis扩展”。
下面咱就说一下Window系统下,wamp环境下配置Redis。
windows下wamp环境下配置Redis
因为我用的操作系统是32位的,所以我提供下载的也是32位的,请在文章最后点击下载。
解压下载的文件放到wamp安装的目录下,我的wamp安装目录是在D盘,所以直接放到D:\Program Files\wamp\Redis。然后运行如下的命令:
D: //移动到D盘
cd "Program Files\wamp\Redis" //移动到Redis目录
redis-server.exe redis.conf //启动Redis服务
执行以上命令之后,你会看到如下界面,即表示Redis服务启动成功。
提示:1、执行命令,要以管理员身份运行;2、命令窗口是不能关闭,关闭即表示关闭Redis服务。
在运行Redis服务成功后,并不是表示直接就可以在php中使用Redis了。你需要在php扩展中进行配置。
运行phpinfo(),查看:PHP Version、TS or NTS、VC版本,然后下载相应的phpredis文件。如下图所示:
对照以上的版本,我下载对应的文件phpredis_5.4_vc9文件。把此文件下载解压,到php目录下的ext目录下。然后在php.ini,加入如下配置:
extension=php_igbinary.dll
extension=php_redis.dll
重启wamp所有服务,以使刚才更改的配置生效。执行phpinfo()后,你可以看到redis已经加载成功。安装完成之后,你可以创建一个php测试文件,你可以查看“Ubuntu 下安装及配置php redis扩展”中的测试方法