一、方案1
方案1特别简单,直接用ini_set设置session的存储方式和存储路径即可,如下:
ini_set('session.save_handler', 'redis'); ini_set('session.save_path', 'tcp://127.0.0.1:6379?auth=123456');这样,我们的session信息就可以保存到redis中了。如下图:
二、方案2
方案2是使用session_set_save_handler来实现session的存储。
1、配置redis参数
//redis配置 $GLOBALS['config']['redis'] = [ 'host' => '127.0.0.1', // redis主机 'port' => 6379, // redis端口 'password' => '', // 密码 'select' => 0, // 操作库 'expire' => 3600, //有效期 'timeout' => 0, // 连接超时时间(单位:毫秒) 'prefix' => 'PHPREDIS_SESSION:', // key前缀 ];
2、存储类
<?php class SessionRedis extends SessionHandler { protected $handler = null; protected $config = [ 'host' => '127.0.0.1', // redis主机 'port' => 6379, // redis端口 'password' => '', // 密码 'select' => 0, // 操作库 'expire' => 3600, // session有效期 'timeout' => 0, // 连接超时时间(单位:毫秒) 'prefix' => '', // key前缀 ]; public function __construct($config = []) { $this->config = array_merge($this->config, $config); //var_dump($this->config); } /** * 打开Session * @access public * @param string $savePath * @param mixed $sessName */ public function open($savePath, $sessName) { // 检测php环境 if (!extension_loaded('redis')) { throw new Exception('not support:redis'); } $this->handler = new Redis(); //连接 $this->handler->connect($this->config['host'], $this->config['port'], $this->config['timeout']); //密码 if('' != $this->config['password']) { $this->handler->auth($this->config['password']); } //选择数据库 if(0 != $this->config['select']) { $this->handler->select($this->config['select']); } return true; } /** * 关闭Session * @access public */ public function close() { $this->gc(ini_get('session.gc_maxlifetime')); $this->handler->close(); $this->handler = null; return true; } /** * 读取Session * @access public * @param mixed $sessID */ public function read($sessID) { return $this->handler->get($this->config['prefix'] . $sessID); } /** * 写入Session * @access public * @param string $sessID * @param String $sessData * @return bool */ public function write($sessID, $sessData) { if($this->config['expire']) { return $this->handler->setex($this->config['prefix'] . $sessID, $this->config['expire'], $sessData); } else { return $this->handler->set($this->config['prefix'] . $sessID, $sessData); } } /** * 删除Session * @access public * @param string $sessID * @return bool */ public function destroy($sessID) { return $this->handler->delete($this->config['prefix'] . $sessID); } /** * Session 垃圾回收 * @access public * @param string $sessMaxLifeTime * @return true */ public function gc($sessMaxLifeTime) { return true; } }
3、实现
<?php /** * 将session放入redis中 */ header("Content-type: text/html; charset=utf-8"); error_reporting(E_ALL); define('DIR', dirname(__FILE__)); //引入配置文件 require_once DIR.'/config.php'; //引入库文件 require_once DIR.'/lib/SessionRedis.php'; //方法1:直接设置session保存方式 //ini_set('session.save_handler', 'redis'); //ini_set('session.save_path', 'tcp://127.0.0.1:6379'); //方法2:通过session句柄的方式 //初始化session句柄 $s_handler = new SessionRedis($GLOBALS['config']['redis']); session_set_save_handler( array($s_handler, 'open'), array($s_handler, 'close'), array($s_handler, 'read'), array($s_handler, 'write'), array($s_handler, 'destroy'), array($s_handler, 'gc') ); register_shutdown_function('session_write_close'); session_start(); $user_info = $_SESSION['u2']; if(empty($user_info)) { if(!empty($_POST)) { $_SESSION['u2'] = $_POST; header('Location: /redis_session.php'); } else { echo <<<EOT <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title> 用户登录 </title> </head> <body> <form action="" method="POST"> 用户名: <input type="text" name="username" value="" /> 密码: <input type="password" name="password" value="" /> <input type="submit" value="提交" /> </form> </body> </html> EOT; } } else { //查看session的位置 var_dump($user_info); $_SESSION['u1'] = ['test' => 'i am test', 'test2' => 'i am test2']; }
好了,一切就是这么简单。
但是,有个很奇怪的问题,我的php版本是5.4.45的,在用session_set_save_handler的时候,如果使用如下的方式:
session_set_save_handler ( SessionHandlerInterface $sessionhandler
[, bool $register_shutdown
= true ] )
程序会报502错误,只能改成
bool session_set_save_handler ( callable $open
, callable $close
, callable $read
, callable $write
, callable $destroy
, callable $gc
[, callable $create_sid
[, callable $validate_sid
[, callable $update_timestamp
]]] )这种方式。