PHP实现redis存储session

一、首先实现SessionHandlerInterface(此接口PHP>5.4.0),如下

<?php
/**
 * 以db的方式存储session
 */
namespace OC\Session;

class redisSession implements \SessionHandlerInterface{
    /**
     * 保存session的redis的信息
     */
    private $_options = array(
        'handler' => null, //redis连接句柄
        'host' => null,
        'port' => null,
        'lifeTime' => null,
    );
    /**
     * 构造函数
     * @param $options 设置信息数组
     */
    public function __construct($options=array()){
        if(!class_exists("redis", false)){
            die("必须安装redis扩展");
        }
        if(!isset($options['lifeTime']) || $options['lifeTime'] <= 0){
            $options['lifeTime'] = ini_get('session.gc_maxlifetime');
        }
        $this->_options = array_merge($this->_options, $options);
    }
    /**
     * 开始使用该驱动的session
     */
    public function begin(){
        if($this->_options['host'] === null ||
            $this->_options['port'] === null ||
            $this->_options['lifeTime'] === null
        ){
            return false;
        }
        //设置session处理函数
        session_set_save_handler(
            array($this, 'open'),
            array($this, 'close'),
            array($this, 'read'),
            array($this, 'write'),
            array($this, 'destory'),
            array($this, 'gc')
        );
    }
    /**
     * 自动开始回话或者session_start()开始回话后第一个调用的函数
     * 类似于构造函数的作用
     * @param $savePath 默认的保存路径
     * @param $sessionName 默认的参数名,PHPSESSID
     */
    public function open($savePath, $sessionName){
        if(is_resource($this->_options['handler'])) return true;
        //连接redis
        $redisHandle = new \Redis();
        $redisHandle->connect($this->_options['host'], $this->_options['port']);
        if(!$redisHandle){
            return false;
        }
        $this->_options['handler'] = $redisHandle;
        $this->gc(null);
        return true;
    }
    /**
     * 类似于析构函数,在write之后调用或者session_write_close()函数之后调用
     */
    public function close(){
        return $this->_options['handler']->close();
    }
    /**
     * 读取session信息
     * @param $sessionId 通过该Id唯一确定对应的session数据
     * @return session信息/空串
     */
    public function read($sessionId){
        return $this->_options['handler']->get($sessionId);
    }
    /**
     * 写入或者修改session数据
     * @param $sessionId 要写入数据的session对应的id
     * @param $sessionData 要写入的数据,已经序列化过了
     */
    public function write($sessionId, $sessionData){
        return $this->_options['handler']->setex($sessionId, $this->_options['lifeTime'], $sessionData);
    }
    /**
     * 主动销毁session会话
     * @param $sessionId 要销毁的会话的唯一id
     */
    public function destroy($sessionId){
        return $this->_options['handler']->delete($sessionId) >= 1 ? true : false;
    }
    /**
     * 清理绘画中的过期数据
     * @param 有效期
     */
    public function gc($lifeTime){
        //获取所有sessionid,让过期的释放掉
        $this->_options['handler']->keys("*");
        return true;
    }
}
以上就是一个完整的实现接口的类,在此封装成一个文件
二、调用时使用方法:
session_set_save_handler(\OC::$server->getRedisSession(),true);
register_shutdown_function('session_write_close');
session_start();
也就是在session_start()方法之前调用,相当于告诉session存储位置变成redis存储,至此,以后使用的所有$_SESSION方法存储的数据都会自动放到redis中去,而存储用的key值就是session_id().
三、解释:

\OC::$server->getRedisSession()

以上的调用对象的方法时使用了pimple容器存储对象并调用的方式。具体如下使用:

namespace OC;
class Server extends SimpleContainer implements IServerContainer {

在此server类中注册加入对象,

$this->registerService('RedisSession',function (Server $c) {
   return new \OC\Session\redisSession(
      $c->getSystemConfig()->getValue('redis')
   );
});
获取对象方式:

/**
 * 新增的获取用户redissession的方法
 */
public function getRedisSession() {
   return $this->query('RedisSession');
}
其实也就是
session_set_save_handler(\OC::$server->getRedisSession(),true);中的
\OC::$server->getRedisSession()

就是上面一、中的类的对象

参考:http://www.tuicool.com/articles/yeeyume

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值