mysql 存储 session
需求:使用 mysql 存储 Session,百度之后代码稍作修改并总结如下:
一、先建表:
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`) USING BTREE) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
主要有三个字段,分别是键,数据,过期时间。
代码如下:
define('SESSION_DNS', 'mysql:host=127.0.0.1:3306;dbname=test;charset=utf8mb4');define('SESSION_USR', 'root');define('SESSION_PWD', 'root');define('SESSION_MAXLIFETIME', get_cfg_var('session.gc_maxlifetime'));
class sessionMysql{//创建PDO连接//持久化连接可以提供更好的效率public static function getConnection() {try {$conn = new PDO(SESSION_DNS, SESSION_USR, SESSION_PWD, array(PDO::ATTR_PERSISTENT => TRUE,PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_EMULATE_PREPARES => FALSE));return $conn;} catch (Exception $ex) {}}//自定义的session的open函数function sessionMysqlOpen($savePath, $sessionName) {return TRUE;}//自定义的session的close函数function sessionMysqlClose() {return TRUE;}/** 由于一般不会把用户提交的数据直接保存到session,所以普通情况不存在注入问题。* 且处理session数据的SQL语句也不会多次使用。因此预处理功能的效益无法体现。* 所以,实际工程中可以不必教条的使用预处理功能。*//** sessionMysqlRead()函数中,首先通过SELECT count(*)来判断sessionID是否存在。* 由于MySQL数据库提供SELECT对PDOStatement::rowCount()的支持,* 因此,实际的工程中可以直接使用rowCount()进行判断。*///自定义的session的read函数//SQL语句中增加了“expire > time()”判断,用以避免读取过期的session。function sessionMysqlRead($sessionId) {try {$dbh = self::getConnection();$time = time();$sql = 'SELECT count(*) AS `count` FROM session WHERE skey = ? and expire > ?';$stmt = $dbh->prepare($sql);$stmt->execute(array($sessionId, $time));$data = $stmt->fetch(PDO::FETCH_ASSOC);if ($data['count'] = 0) {return '';}$sql = 'SELECT `data` FROM `session` WHERE `skey` = ? and `expire` > ?';$stmt = $dbh->prepare($sql);$stmt->execute(array($sessionId, $time));$data = $stmt->fetch(PDO::FETCH_ASSOC);return $data['data'];} catch (Exception $e) {return '';}}//自定义的session的write函数//expire字段存储的数据为当前时间+session生命期,当这个值小于time()时表明session失效。function sessionMysqlWrite($sessionId, $data) {try {$dbh = self::getConnection();$expire = time() + SESSION_MAXLIFETIME;$sql = 'INSERT INTO `session` (`skey`, `data`, `expire`) '. 'values (?, ?, ?) '. 'ON DUPLICATE KEY UPDATE data = ?, expire = ?';$stmt = $dbh->prepare($sql);$stmt->execute(array($sessionId, $data, $expire, $data, $expire));} catch (Exception $e) {echo $e->getMessage();}}//自定义的session的destroy函数function sessionMysqlDestroy($sessionId) {try {$dbh = self::getConnection();$sql = 'DELETE FROM `session` where skey = ?';$stmt = $dbh->prepare($sql);$stmt->execute(array($sessionId));return TRUE;} catch (Exception $e) {return FALSE;}}//自定义的session的gc函数function sessionMysqlGc($lifetime) {try {$dbh = self::getConnection();$sql = 'DELETE FROM `session` WHERE expire < ?';$stmt = $dbh->prepare($sql);$stmt->execute(array(time()));$dbh = NULL;return TRUE;} catch (Exception $e) {return FALSE;}}//自定义的session的session id设置函数/** 由于在session_start()之前,SID和session_id()均无效,* 故使用$_GET[session_name()]和$_COOKIE[session_name()]进行检测。* 如果此两者均为空,则表明session尚未建立,需要为新session设置session id。* 通过MySQL数据库获取uuid作为session id可以更好的避免session id碰撞。*/public static function sessionMysqlId() {if (filter_input(INPUT_GET, session_name()) == '' andfilter_input(INPUT_COOKIE, session_name()) == '') {try {$dbh = self::getConnection();$stmt = $dbh->query('SELECT uuid() AS uuid');$data = $stmt->fetch(PDO::FETCH_ASSOC);$data = str_replace('-', '', $data['uuid']);session_id($data);return TRUE;} catch (Exception $ex) {return FALSE;}}}//session启动函数,包括了session_start()及其之前的所有步骤。public static function startSession() {$handler = new sessionMysql;session_module_name('user');$res = session_set_save_handler(//注册函数array($handler, 'sessionMysqlOpen'),array($handler, 'sessionMysqlClose'),array($handler, 'sessionMysqlRead'),array($handler, 'sessionMysqlWrite'),array($handler, 'sessionMysqlDestroy'),array($handler, 'sessionMysqlGc'));register_shutdown_function('session_write_close');sessionMysql::sessionMysqlId();session_start();}
}
测试代码如下:
$handler = sessionMysql::startSession();$_SESSION['user'] = 'yibin';$_SESSION['password'] = 'yibin9408';$_SESSION['over'] = '111';
结果如下图则代表插入成功:
以下是其他博文摘来的,可以看看:
二、简介
1、使用MySQL保存session,需要保存三个关键性的数据:session id、session数据、session生命期。
2、考虑到session的使用方式,没必要使用InnoDB引擎,MyISAM引擎可以获得更好的性能。如果环境允许,可以尝试使用MEMORY引擎。
3、保存session数据的列,有需要的话,可以使用utf8或utf8mb4字符集;保存session id的列则没有必要,一般情况使用ascii字符集就可以了,可以节约存储成本。
4、保存session生命期的列,可以根据工程需要进行设计。比如datetime类型、timestamp类型、int类型。对于datetime、int类型可以保存session生成时间或过期时间。
5、如果有必要可以扩展session表的列并修改读、写函数以支持(维护)相关列来保存诸如用户名等信息。
6、当前版本,只要通过session_set_save_handler注册自定义的会话维护函数就可以,不需要在其之前使用session_module_name('user')函数。
7、当read函数获取数据并返回,PHP会自动对其进行反序列化,一般情况请不要对数据进行更改。
8、PHP传递给write函数的date参数是序列化之后的session数据,直接保存即可,一般情况请不要对数据进行更改。
9、按照本段代码的逻辑,PHP配置选项关于会话生命期的设置已经不再有效,这个值可以自行维护,不一定需要通过get_cfg_var获取。
10、sessionMysqlId()函数是为了避免大用户量、多台Web服务器情况下的碰撞,一般情况PHP自动生成的session id是可以满足用户要求的。
三、需求
当用户量非常大,需要多台服务器提供应用的时候,使用MySQL存储会话相对使用会话文件具有一定的优越性。比如具有最小的存储开销,比如可以避免文件共享带来的复杂性,比如可以更好的避免发生碰撞,比如相比会话文件共享具有更好的性能。总体上来说,当访问量剧增的时候,如果使用数据库保存会话带来的问题是线性增长的,那么使用会话文件带来的问题几乎是爆炸性的。好吧,换一个更直白的说法吧:如果您的应用用户量不大,其实让PHP自己处理session就好了,没必要考虑MySQL。
好了!大致就是上面这样吧。可以去尝试下。
mysql 存储 session相关推荐
- mysql dba系统学习(20)mysql存储引擎MyISAM
mysql存储引擎MyISAM 1,创建myisam表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 mysql> creat ...
- DBA(七):PXC、MySQL存储引擎
PXC PXC概述 PXC介绍 Percona XtrDB Cluster(简称PXC) 是基于Galera的mysql奥可用集群解决方案 Galera Cluster是Codership公司开发的一 ...
- yii2设置session时间_关于 Swoft 2.0 版本用 Redis 存储 session 时配置问题
Swoft 2.0 在 session 配置上和 1.0 还是有一些不同地方,而关于这些在 github 上完全没有任何说明,甚至连文档也没有.经过逐步梳理源代码(其中要理解他的 "注解&q ...
- MySQL 存储引擎和锁
MySQL 存储引擎和锁 =============================================================================== 存储引擎: ...
- mysql被禁用了怎么办_数据库mysql存储遇到禁用怎么办?
原标题:数据库mysql存储遇到禁用怎么办? 我们有大量数据要存放的时候,通常会需要使用数据库.不过有些功能因为本身使用的限制,想要放在数据库的时候就会出现禁用.这里我们以mysql数据库和常用的se ...
- redis安装、持久化、数据类型、常用操作、操作键值、安全设置、慢查询日志、存储session、主从配置、集群介绍、集群搭建配置、集群操作,php安装redis扩展...
21.9 redis介绍 21.10 redis安装 21.11 redis持久化 21.12 redis数据类型 21.13/21.14/21.15 redis常用操作 21.16 redis操作键 ...
- 对 PHP SESSION 的深刻认识(三)---- 数据库存储session
前言: 本篇博客是继承自我的前面的两篇博客 <对 PHP SESSION 的深刻认识(一)>.<对 PHP SESSION 的深刻认识(二)> 而来的,主要是解决前面的问题. ...
- MySQL——存储引擎与索引应用
文章目录 一. 存储引擎 1.1 MySQL结构 1.2 存储引擎简介 1.3 存储引擎特点 1.3.1 InnoDB 1.3.1.1 InnoDB 基本介绍 1.3.1.2 InnoDB 逻辑存储结 ...
- 浅谈MySQL存储引擎-InnoDBMyISAM
浅谈MySQL存储引擎-InnoDB&MyISAM 存储引擎在MySQL的逻辑架构中位于第三层,负责MySQL中的数据的存储和提取.MySQL存储引擎有很多,不同的存储引擎保存数据和索引的方式 ...
最新文章
- .net 学习 报错 Invalid temp directory in chart handler configuration [c:\TempImageFiles\]
- 拜占庭将军问题与中本聪
- 修改linux swap空间的swappiness,降低对硬盘的缓存
- ASP.NET多线程的使用
- 只需12 个步骤,就能在AWS中创建自定义VPC,用过都惊了!
- centos 需要哪些常用端口_仓库加盟:电商仓库需要配备哪些常用仓储设备
- 在VMware workstation 9.0中安装Windows server 2012 和 Hyper-v(虚拟机中安装虚拟机)
- 最简单的基于FFmpeg的移动端例子:Android HelloWorld
- 可以在python3下面用的pyh
- 一键导出微信读书的书籍和笔记
- 沧小海基于xilinx srio核的学习笔记之第三章 xilinx srio核介绍(二)HELLO格式和流控
- 第五章:腾讯云有哪些产品
- (转自MBA智库百科)弗兰克·吉尔布雷斯
- 自定义输入框可一键清除
- 王者荣耀android加ios好友,王者荣耀安卓和苹果能加好友吗 安卓和ios怎么加好友...
- 【优化控制】基于遗传算法实现优化LQR控制器含Matlab源码
- 华为宿舍租金涨价 数千员工群情激昂
- 搞笑的哈佛大学精神病测试题
- LBM模拟方法学习篇1:安装Xshell和Xftp
- 软件测试——bug提交及跟踪流程
热门文章
- 搜狗输入法不能输入中文,shift切换为中文输出的还是英文--------解决方法
- ubuntu gcc 安装 使用
- 如何控制蜂鸣器的响动频率
- 智慧新零售时代 让数字化赋能会员营销
- Gerber 各层的含义
- mybatisplus代码生成报错:Exception in thread “main“ java.lang.NoClassDefFoundError: org/apache/velocity
- QGraphicsView放大和缩小下鼠标位置使用鼠标滚轮
- 《炬丰科技-半导体工艺》化合物半导体未来动力
- 嵌入式课程设计总结(八)
- 05-使用Redis缓存数据,管理员相关数据表