class RedisSession {
// 默认配置名称(使用load_config加载)
private $_default_config_path = 'package/cache/redis_session';
// sessions 最大生存时间,单位:秒
public $max_life_time = 0;
// 用作生成 session_id 的标识值
public $key_preffix = '';
// \package\cache\Redis 类的一个实例
public $redis = null;
 
/**
* 构造函数,自动赋予默认值
*
* @access public
* @param objcet $redis 指定一个特定的 \package\cache\Redis 实例
* @return void
*/
public function __construct($redis=null) {
$conf = load_config($this -> _default_config_path);
if (!is_array($conf) or empty($conf)) {
to_log(MAIN_LOG_ERROR, '', __CLASS__ . ':' . __FUNCTION__ . ': 默认配置为空');
return;
}
isset($conf['max_life_time']) and $this -> max_life_time = $conf['max_life_time'];
isset($conf['key_preffix']) and $this -> key_preffix = $conf['key_preffix'];
empty($redis) and $redis = g('\\package\\cache\\Redis');
$this -> redis = $redis;
}
/**
* 调用这个方法代替session_start
*
* @access public
* @return void
*/
public function start() {
session_set_save_handler(
array(&$this, 'open'),
array(&$this, 'close'),
array(&$this, 'read'),
array(&$this, 'write'),
array(&$this, 'destroy'),
array(&$this, 'gc'),
array(&$this, 'create_id')
);
 
// 下面这行代码可以防止使用对象作为会话保存管理器时可能引发的非预期行为
register_shutdown_function('session_write_close');
session_start();
}
/**
* 获取redis缓存变量名
*
* @access public
* @param string $str 使用该字符串生成key
* @return string
*/
public function get_cache_key($str) {
$key = md5($str);
return $key;
}
/**
* 自定义session_id
*
* @access public
* @return string
*/
public function create_id() {
        $time = time();
        $ip = $this -> _get_ip();
        $uid = uniqid($this -> key_preffix, TRUE);
        $rand = get_rand_str(13);
        $key_str = 'session_id:ip:' . $ip . ':uid:' . $uid . ':time:' . $time . ':rand:' . $rand;
        $key = sha1($key_str);
        return $key;
}
/**
* session_open 将提交到该函数
*
* @access public
* @return boolean
*/
public function open($sess_id) {
$cache_key = $this -> get_cache_key(session_id());
$ret = $this -> redis -> expire($cache_key, $this -> max_life_time);
 
return $ret;
}
 
/**
* session_close将提交到该函数
*
* @access public
* @return boolean
*/
public function close() {
return true;
}
 
/**
* session_read将提交到该函数
*
* @access public
* @param string $sess_id session_id
* @return mixed
*/
public function read($sess_id) {
$cache_key = $this -> get_cache_key($sess_id);
$ret = $this -> redis -> get($cache_key);
return $ret;
}
 
/**
* session_write将提交到该函数
*
* @access public
* @param string $sess_id session_id
* @param string $sess_data session数据
* @return boolean
*/
public function write($sess_id, $sess_data) {
$cache_key = $this -> get_cache_key($sess_id);
$ret = $this -> redis -> set($cache_key, $sess_data, $this -> max_life_time);
return $ret;
}
/**
* session_destroy将提交到该函数
*
* @access public
* @param string $sess_id session_id
* @return boolean
*/
public function destroy($sess_id) {
session_unset();
$cache_key = $this -> get_cache_key($sess_id);
$ret = $this -> redis -> delete($cache_key);
return $ret;
}
/**
* session的gc回收将托管到该方法
*
* @access public
* @return void
*/
public function gc() {
}
 
    private function _get_ip(){
     static $ip = NULL;
     if ($ip !== NULL) return $ip;
    
     if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
     $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
     is_array($ip) and $ip = array_shift($ip);
     if (check_data($ip, 'ip')) return $ip;
     }
    
     if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
     $ip = $_SERVER['HTTP_CLIENT_IP'];
     if (check_data($ip, 'ip')) return $ip;
     }
    
     if (!empty($_SERVER['REMOTE_ADDR'])) {
     $ip = $_SERVER['REMOTE_ADDR'];
     if (check_data($ip, 'ip')) return $ip;
     }
    
     $ip = '';
     return $ip;
    }
}

使用redis接管session的更多相关文章

  1. PHP中使用Redis接管文件存储Session详解

    前言 php默认使用文件存储session,如果并发量大,效率会非常低.而redis对高并发的支持非常好,可以利用redis替换文件来存储session. 最近就遇到了这个问题,之前找了网上的一套直播 ...

  2. PHP中如何使用Redis接管文件存储Session详解

    https://www.jb51.net/article/151580.htm 前言 php默认使用文件存储session,如果并发量大,效率会非常低.而redis对高并发的支持非常好,可以利用red ...

  3. 分布式中使用Redis实现Session共享(二)

    上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见的session开始,刚好也重新学习一遍session的实现原理.在阅读之前假设你已经会使用nginx+i ...

  4. [转]分布式中使用Redis实现Session共享(二)

    本文转自:http://www.cnblogs.com/yanweidie/p/4678095.html 上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见 ...

  5. (转)分布式中使用Redis实现Session共享(二)

    上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见的session开始,刚好也重新学习一遍session的实现原理.在阅读之前假设你已经会使用nginx+i ...

  6. php用redis保存session

    1.修改php.ini中session配置: ini_set('session.save_handler', 'redis');ini_set('session.save_path', 'tcp:// ...

  7. nodejs express下使用redis管理session

    Session实现原理 实现请求身份验证的方式很多,其中一种广泛接受的方式是使用服务器端产生的Session ID结合浏览器的Cookie实现对Session的管理,一般来说包括以下4个步骤: 服务器 ...

  8. Tomcat7基于Redis的Session共享实战二

    目前,为了使web能适应大规模的访问,需要实现应用的集群部署.集群最有效的方案就是负载均衡,而实现负载均衡用户每一个请求都有可能被分配到不固定的服务器上,这样我们首先要解决session的统一来保证无 ...

  9. Tomcat7基于Redis的Session共享实战一

    本文主要介绍如何使用redis对tomcat7的session进行托管. 1.安装Redisredis安装比较简单,此处略过. 2.配置两个Tomcat在本机上配置两个Tomcat,分别为tomcat ...

随机推荐

  1. pygame-KidsCanCode系列jumpy-part12-platform图片

    目前为止,Player的站立.行走.跳跃都是动画了,只有跳板(即:Platform类)还是难看的矩形,这节我们把Platform也换成图片: 原来的Platform类长这个样子: class Plat ...

  2. [asp.net core]The requested page cannot be accessed because the related configuration data for the page is invalid.

    bug HTTP Error 500.19 - Internal Server Error The requested page cannot be accessed because the rela ...

  3. 输出cglib以及jdk动态代理产生的class文件

      --该设置用于输出jdk动态代理产生的类 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles&q ...

  4. Xtrabackup简介

    Xtrabackup是由 Percona 开发的一个开源软件,可实现对 InnoDB 的数据备份,支持在线热备份(备份时不影响数据读写),特点如下: 备份过程快速.可靠: 备份过程不会打断正在执行的事 ...

  5. 开源一个CSV解析器(附设计过程 )

    在ExcelReport支持csv的开发过程中,需要一个NETStandard的csv解析器.在nuget上找了几个试用,但都不太适合. 于是,便有了:AxinLib.IO.CSV. 先看看怎么用: ...

  6. MySQL InnoDB 引擎的持久性与性能

    MySQL 事务的 ACID 特性中,D 代表持久性(Durability):在使用 InnoDB 引擎时,当返回客户端一个成功完成事务的确认时, InnoDB 就会保证数据的一致性,即使该数据在此时 ...

  7. SQL2008R2的 遍历所有表更新统计信息 和 索引重建

    [2.以下是更新统计信息] DECLARE UpdateStatisticsTables CURSOR READ_ONLY FOR SELECT sst.name, Schema_name(sst.s ...

  8. [20170713] 无法访问SQL Server

    背景: 朋友的环境第二天突然访问不了SQL Server,远程SQL Server用户无法登陆,但是本地SQL Server用户登录正常. 报错: 用户XX登录失败(MicroSoft SQL Ser ...

  9. ssh远程登录不上的处理

    最近ssh远程主机突然登录不上,提示如下: 后来咨询了一下云主机的客服,估计我们的主机时多次尝试密码错误被系统屏蔽IP了.于是问了一下同事,确实有同事最近密码错误多次尝试的问题. 于是按照客服给的方法 ...

  10. IOS-电话拦截

    IOS10的电话拦截理念与android不一样,基于隐私保护的理念IOS没把对方号码送给应用,因此需要反过来由app把需要识别或拦截的电话存入系统数据库.这一功能通过Call Directory Ex ...