PHP使用Redis存储Session
对于大访问量的网站来说,会有许多的客户端和服务端建立链接,就会生成许多 Session 文件,由于 Session 文件是存储在硬盘上的,因此每次服务器去读取这些 Session 文件都要经过许多的 I/O 操作。
PHP 中可使用 session_set_save_handle() 函数自定义 Session 保存函数(如打开、关闭、写入、读取等),其语法如下:
该函数的参数说明如下:
此回调函数操作成功返回 true,反之返回 false。
此回调函数操作成功返回 true,反之返回 false。
在自动开始会话或者通过调用 session_start() 函数手动开始会话之后,PHP 内部调用 read 回调函数来获取会话数据。在调用 read 之前,PHP 会调用 open 回调函数。
read 回调返回的序列化之后的字符串格式必须与 write 回调函数保存数据时的格式完全一致。PHP 会自动反序列化返回的字符串并填充 $_SESSION 超级全局变量。虽然数据看起来和 serialize() 函数很相似,但是它们是不同的。
序列化会话数据的过程由 PHP 根据 session.serialize_handler 设定值来完成。序列化后的数据将和会话 ID 关联在一起进行保存。当调用 read 回调函数获取数据时,所返回的数据必须和传入 write 回调函数的数据完全保持一致。PHP 会在脚本执行完毕或调用 session_write_close() 函数之后调用此回调函数。
注意,在调用完此回调函数之后,PHP 内部会调用 close 回调函数。
PHP 会在输出流写入完毕并且关闭之后才调用 write 回调函数,所以在 write 回调函数中的调试信息不会输出到浏览器中。如果需要在 write 回调函数中使用调试输出,建议将调试输出写入到文件。
此回调函数操作成功返回 true,反之返回 false。
此回调函数操作成功返回 true,反之返回 false。
首先编写一个管理 Session 的类 sessionmanager,代码如下:
在该类的构造函数中,使用 session_set_save_handler() 设置 Session 的处理函数,实例化该类时便完成了用指定函数接管系统处理 Session 的工作。
在 write 回调函数中,以传入的 sessionID 作为 key,以 Session 的值作为 redis 中 key 的值存入 Redis,并设置过期时间为 60 秒;read 方法以传入的 sessionID 为 key 从 Redis 取出相应的 Session 值。destroy 可根据传入的 sessionID 删除 Redis 中的 Session。
我们编写另外一个设置 Session 的脚本,并引入 sessionmanager.php 文件,实例化 sessionmanager 类,代码如下:
PHP 中可使用 session_set_save_handle() 函数自定义 Session 保存函数(如打开、关闭、写入、读取等),其语法如下:
bool session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc [, callable $create_sid ] )
如果想使用 PHP 内置的会话存储机制之外的方式,可以使用本函数。例如,可以自定义会话存储函数来将会话数据存储到数据库。该函数的参数说明如下:
open(string$savePath,string$sessionName)
open 回调函数类似于类的构造函数,在会话打开的时候被调用。这是自动开始会话或者通过调用 session_start() 手动开始会话之后第一个被调用的回调函数。此回调函数操作成功返回 true,反之返回 false。
close()
close 回调函数类似于类的析构函数。在 write 回调函数调用之后调用。当调用 session_write_close() 函数之后,也会调用 close 回调函数。此回调函数操作成功返回 true,反之返回 false。
read(string$sessionId)
如果会话中有数据,那么 read 回调函数必须返回将会话数据编码(序列化)后的字符串。如果会话中没有数据,read 回调函数就返回空字符串。在自动开始会话或者通过调用 session_start() 函数手动开始会话之后,PHP 内部调用 read 回调函数来获取会话数据。在调用 read 之前,PHP 会调用 open 回调函数。
read 回调返回的序列化之后的字符串格式必须与 write 回调函数保存数据时的格式完全一致。PHP 会自动反序列化返回的字符串并填充 $_SESSION 超级全局变量。虽然数据看起来和 serialize() 函数很相似,但是它们是不同的。
write(string$sessionId,string$data)
在会话保存数据时会调用 write 回调函数。此回调函数接收当前会话 ID 以及 $_SESSION 中数据序列化之后的字符串作为参数。序列化会话数据的过程由 PHP 根据 session.serialize_handler 设定值来完成。序列化后的数据将和会话 ID 关联在一起进行保存。当调用 read 回调函数获取数据时,所返回的数据必须和传入 write 回调函数的数据完全保持一致。PHP 会在脚本执行完毕或调用 session_write_close() 函数之后调用此回调函数。
注意,在调用完此回调函数之后,PHP 内部会调用 close 回调函数。
PHP 会在输出流写入完毕并且关闭之后才调用 write 回调函数,所以在 write 回调函数中的调试信息不会输出到浏览器中。如果需要在 write 回调函数中使用调试输出,建议将调试输出写入到文件。
destroy($sessionId)
当调用 session_destroy() 函数,或者调用 session_regenerate_id() 函数并且设置 destroy 参数为 true 时会调用此回调函数。此回调函数操作成功返回 true,反之返回 false。
gc($lifetime)
为了清理会话中的旧数据,PHP 会不时地调用垃圾收集回调函数。调用周期由 session.gc_probability 和 session.gc_divisor 参数控制。传入到此回调函数的 lifetime 参数由 session.gc_maxlifetime 设置。此回调函数操作成功返回 true,反之返回 false。
create_sid()
当需要新的会话 ID 时被调用的回调函数。回调函数被调用时无传入参数,其返回值应该是一个字符串格式的、有效的会话 ID。PHP 使用 Redis 来存储 Session
下面举一个关于使用 Redis 代替文件存储 Session 的例子。首先编写一个管理 Session 的类 sessionmanager,代码如下:
<?php class sessionmanager{ private $redis; private $sessionsavepath; private $sessionname; public function __construct(){ $this->redis = new Redis(); $this->redis->connect('10.116.19.14',6400); $reval = session_set_save_handler( array($this,"open"), array($this,"close"), array($this,"read"), array($this,"write"), array($this,"destroy"), array($this,"gc") ); session_start(); } public function open($patn,$name){ return true; } public function close(){ return true; } public function read($id){ $value = $this->redis->get($id); if($value) { return $value; } else { return false; } } public function write($id,$data){ if($this->redis->set($id,$data)) { $this->redis->expire($id,60); return true; } else { return false; } } public function destroy($id) { if($this->redis->delete($id)) { return true; } return false; } public function gc($maxlifetime){ return true; } public function __destruct(){ session_write_close(); //TODO: Implement __destruct() method. } } ?>将以上代码保存为 sessionmanager.php 文件。
在该类的构造函数中,使用 session_set_save_handler() 设置 Session 的处理函数,实例化该类时便完成了用指定函数接管系统处理 Session 的工作。
在 write 回调函数中,以传入的 sessionID 作为 key,以 Session 的值作为 redis 中 key 的值存入 Redis,并设置过期时间为 60 秒;read 方法以传入的 sessionID 为 key 从 Redis 取出相应的 Session 值。destroy 可根据传入的 sessionID 删除 Redis 中的 Session。
我们编写另外一个设置 Session 的脚本,并引入 sessionmanager.php 文件,实例化 sessionmanager 类,代码如下:
<?php include 'sessionmanager.php'; new sessionmanager(); $_SESSION['namehaha'] = 'lixiaolong'; $_SESSION['namehah'] = 'lixiaolong'; $_SESSION['namehaa'] = 'lixiaolong'; $_SESSION['namhaha'] = 'lixiaolong'; $_SESSION['namhaha'] = array('a'=>1,2,3,4,4); ?>保存以上代码为 set.php,另外编写一个可访问 Session 的脚本,代码如下:
<?php include 'sessionmanager.php'; new sessionmanager(); var_dump($_SESSION); ?>保存以上代码为 get.php 文件。测试时先访问 set.php,再访问 get.php,会在浏览器中输出以下结果:
array(4)
{
["namehaha"]=> string(10) "lixiaolong"
["namehah"]=> string(10) "lixiaolong"
["namehaa"]=> string(10) "lixiaolong"
["namhaha"]=> array(5)
{
["a"]=> int(1)
[0]=> int(2)
[1]=> int(3)
[2]=> int(4)
[3]=> int(4)
}
}
redis 127.0.0.1:6400> get ruevh62hlm809d1p2lg2o0fbv7
"namehaha|s:10:\"lixiaolong\";namehah|s:10:\"lixiaolong\"; namehaa|s:10:\"lixiaolong\";namhaha|a:5:{s:1:\"a\";i:1;i:0;i:2;i:1;i:3;i:2;i:4;i:3;i:4;}"
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算