需求:使用 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相关推荐

  1. 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 ...

  2. DBA(七):PXC、MySQL存储引擎

    PXC PXC概述 PXC介绍 Percona XtrDB Cluster(简称PXC) 是基于Galera的mysql奥可用集群解决方案 Galera Cluster是Codership公司开发的一 ...

  3. yii2设置session时间_关于 Swoft 2.0 版本用 Redis 存储 session 时配置问题

    Swoft 2.0 在 session 配置上和 1.0 还是有一些不同地方,而关于这些在 github 上完全没有任何说明,甚至连文档也没有.经过逐步梳理源代码(其中要理解他的 "注解&q ...

  4. MySQL 存储引擎和锁

    MySQL 存储引擎和锁 =============================================================================== 存储引擎:   ...

  5. mysql被禁用了怎么办_数据库mysql存储遇到禁用怎么办?

    原标题:数据库mysql存储遇到禁用怎么办? 我们有大量数据要存放的时候,通常会需要使用数据库.不过有些功能因为本身使用的限制,想要放在数据库的时候就会出现禁用.这里我们以mysql数据库和常用的se ...

  6. 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操作键 ...

  7. 对 PHP SESSION 的深刻认识(三)---- 数据库存储session

    前言: 本篇博客是继承自我的前面的两篇博客 <对 PHP SESSION 的深刻认识(一)>.<对 PHP SESSION 的深刻认识(二)> 而来的,主要是解决前面的问题. ...

  8. MySQL——存储引擎与索引应用

    文章目录 一. 存储引擎 1.1 MySQL结构 1.2 存储引擎简介 1.3 存储引擎特点 1.3.1 InnoDB 1.3.1.1 InnoDB 基本介绍 1.3.1.2 InnoDB 逻辑存储结 ...

  9. 浅谈MySQL存储引擎-InnoDBMyISAM

    浅谈MySQL存储引擎-InnoDB&MyISAM 存储引擎在MySQL的逻辑架构中位于第三层,负责MySQL中的数据的存储和提取.MySQL存储引擎有很多,不同的存储引擎保存数据和索引的方式 ...

最新文章

  1. .net 学习 报错 Invalid temp directory in chart handler configuration [c:\TempImageFiles\]
  2. 拜占庭将军问题与中本聪
  3. 修改linux swap空间的swappiness,降低对硬盘的缓存
  4. ASP.NET多线程的使用
  5. 只需12 个步骤,就能在AWS中创建自定义VPC,用过都惊了!
  6. centos 需要哪些常用端口_仓库加盟:电商仓库需要配备哪些常用仓储设备
  7. 在VMware workstation 9.0中安装Windows server 2012 和 Hyper-v(虚拟机中安装虚拟机)
  8. 最简单的基于FFmpeg的移动端例子:Android HelloWorld
  9. 可以在python3下面用的pyh
  10. 一键导出微信读书的书籍和笔记
  11. 沧小海基于xilinx srio核的学习笔记之第三章 xilinx srio核介绍(二)HELLO格式和流控
  12. 第五章:腾讯云有哪些产品
  13. (转自MBA智库百科)弗兰克·吉尔布雷斯
  14. 自定义输入框可一键清除
  15. 王者荣耀android加ios好友,王者荣耀安卓和苹果能加好友吗 安卓和ios怎么加好友...
  16. 【优化控制】基于遗传算法实现优化LQR控制器含Matlab源码
  17. 华为宿舍租金涨价 数千员工群情激昂
  18. 搞笑的哈佛大学精神病测试题
  19. LBM模拟方法学习篇1:安装Xshell和Xftp
  20. 软件测试——bug提交及跟踪流程

热门文章

  1. 搜狗输入法不能输入中文,shift切换为中文输出的还是英文--------解决方法
  2. ubuntu gcc 安装 使用
  3. 如何控制蜂鸣器的响动频率
  4. 智慧新零售时代 让数字化赋能会员营销
  5. Gerber 各层的含义
  6. mybatisplus代码生成报错:Exception in thread “main“ java.lang.NoClassDefFoundError: org/apache/velocity
  7. QGraphicsView放大和缩小下鼠标位置使用鼠标滚轮
  8. 《炬丰科技-半导体工艺》化合物半导体未来动力
  9. 嵌入式课程设计总结(八)
  10. 05-使用Redis缓存数据,管理员相关数据表