1.代码参考:http://www.thinkphp.cn/extend/852.html
2.建一个会话表:# 创建 session 会话表
CREATE TABLE `session_table`(
`session_id` VARCHAR(255) NOT NULL COMMENT '会话ID',
`session_value` BLOB NULL COMMENT '会话数据',
`session_expire` INT(13) UNSIGNED NOT NULL COMMENT '存活时间',
UNIQUE INDEX `session_id` (`session_id`)
)ENGINE = InnoDB CHARSET = utf8 COLLATE utf8_general_ci COMMENT = '会话表';2.修改后:<?php
namespace driver\session;
use SessionHandler;
use think\Db;
use think\Config;
use think\Exception;
class Mysql extends SessionHandler
{
protected $table_name = null; // 存放Session的表名
protected $config = null; // config.php 中 session 的值
public function __construct($config = [])
{
if(isset($config['database'])){
// config.php 中 session 的 database 字段是否为数组
if(is_array($config['database'])){
// config.php 中 session 的 database 字段是否为空
if (!empty($config['database'])){
$database = $config['database'];
}else{
throw new Exception('session error: 数据库连接设置错误');
}
}else{
throw new Exception('session error: 数据库连接设置错误');
}
unset($config['database']);
}else{
// 如果没有设置,则调取 database.php 中的配置
$database = Config::get('database');
}
$this->config = $config;
$this->database = $database;
$this->table_name = $this->config['prefix'].$this->config['table_name'];
}
public function open($save_path, $session_name)
{
return true;
}
public function close()
{
$this->gc(ini_get('session.gc_maxlifetime'));
return true;
}
// 读取 Session
public function read($session_id)
{
$params = [
'session_id' => $this->config['prefix'].$session_id,
'time' => time()
];
$result = Db::table($this->table_name)
->where('session_id',$params['session_id'])
->where('session_expire', '>', $params['time'])
->find();
if($result){
return $result['session_value'];
}
return '';
}
// 写入 Session
public function write($session_id, $session_data)
{
// 再调用 Session 类的相关静态方法时,会自动开启会话
// 如果不添加该判断,则数据库会写入一个空 $session_value 的条目
if (empty($session_data)) return false;
$params = [
'session_id' => $this->config['prefix'].$session_id,
'session_value' => $session_data,
'newExpir' => time() + $this->config['session_expire']
];
$is_exist = Db::table($this->table_name)
->where('session_id',$params['session_id'])
->find();
// 根据返回值来判断更新、新增的操作
if($is_exist){
DB::table($this->table_name)
->where('session_id',$params['session_id'])
->update([
'session_value' => $params['session_value'],
'session_expire' => $params['newExpir']
]);
}else{
$result = Db::table($this->table_name)
->insert([
'session_id' => $params['session_id'],
'session_value' => $params['session_value'],
'session_expire' => $params['newExpir']
]);
}
return $result ? true : false;
}
// 删除 Session
public function destroy($session_id)
{
$params = [
'session_id' => $this->config['prefix'].$session_id,
];
$result = Db::table($this->table_name)
->where('session_id',$params['session_id'])
->delete();
return $result ? true : false;
}
// Session 垃圾回收
public function gc($maxlifetime)
{
$params = [
'time' => time()
];
$result = Db::table($this->table_name)
->where('session_expire','
->delete();
return $result ? true : false;
}
}使用方法:
1.将附件放到 extend 目录下
2.存放目录 extend/driver/session/Mysql.php
3.config.php 中的 session 选项修改为'session' => [
// 驱动方式 支持redis memcache memcached
'type' => 'driver\session\Mysql', // extend/driver/session/Mysql.php
// SESSION 存活时间
'session_expire' => 3600,
// SESSION 数据表表名
'table_name' => 'session',
// SESSION 前缀
'prefix' => 'mapi_',
// 是否自动开启 SESSION
'auto_start' => true
],3. 注意:session 中 type(驱动模式)一定要跟着文件名一样不然会提示 error session handler ,下面这段是代码是用来检测session中启动模式的名称(位于thinkphp\library\think\Session.php Line 98)$class = false !== strpos($config['type'], '\\') ? $config['type'] : '\\think\\session\\driver\\' . ucwords($config['type']);PS:由于使用了 Db 类,所以我的 open 和 close return true,再写这个驱动的过程中发现了一个问题,就是使用Session类的静态方法has都会向写入一个空session_value的条目(我是用Session::has来判断是否登录账号和重复登录的检查),所以在 write 方法开头添加一个判断来阻止写入空的session_value
写的不是很好见谅了