class RedisCookie {
// 默认配置名称(使用load_config加载)
private $_default_config_path = 'package/cache/redis_cookie';
// 当前用作服务端保存cookie数据的哈希名
private $_cookie_id = null;
// cookie中的每个变量(包含cookie_id本身), 在redis中的最大生存时间
public $max_life_time = 0;
// 用作生成 cookie_id 的标识值
public $key_preffix = '';
// 客户端cookie_id的变量名
public $id_client_var = '';
// 客户端cookie_id的保存domain
public $id_client_host = '';
// cookie_id保存于客户端时的有效时长,单位:秒
public $id_valid_time = 0;
// \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'];
isset($conf['id_client_var']) and $this -> id_client_var = $conf['id_client_var'];
isset($conf['id_client_host']) and $this -> id_client_host = $conf['id_client_host'];
isset($conf['id_valid_time']) and $this -> id_valid_time = $conf['id_valid_time'];
empty($redis) and $redis = g('\\package\\cache\\Redis');
$this -> redis = $redis;
}
/**
* 类似 session_start, 使用该类时调用这个方法初始化
*
* @access public
* @return void
*/
public function start() {
$this -> get_now_id();
}
/**
* 获取cookie_id
*
* @access public
* @param integer $id 指定使用该id作为cookie_id
* @return string
*/
public function get_now_id($id='') {
if (!empty($id)) {
$this -> _cookie_id = $id;
$this -> save_id();
$cookie_id = $id;
}else {
$cookie_id = $this -> get_id();
}
return $cookie_id;
}
/**
* 获取指定cookie数据
*
* @access public
* @param string $name 变量名
* @return mixed 失败返回(bool)false,否则返回(string)
*/
public function get($name='') {
$name = strval($name);
$hash = $this -> get_now_id();
if (empty($name) or empty($hash)) {
return false;
}
$key = $this -> get_cache_key($name);
try {
$redis = $this -> redis -> get_handler();
$ret = $redis -> hGet($hash, $key);
}catch(\RedisException $e) {
return false;
}
if ($ret === false) return false;
 
$ret = json_decode($ret, true);
if (!is_array($ret) or empty($ret)) return false;
if ($ret['ttl'] <= time()) {
$this -> delete($key);
return false;
}
$this -> renew();
$ret = $ret['data'];
return $ret;
}
/**
* 设置指定cookie数据
*
* @access public
* @param string $name 缓存变量名
* @param mixed $value 缓存变量值
* @param string $ttl 有效的生存时间
* @return boolean
*/
public function set($name, $value, $ttl=3600) {
$name = strval($name);
$hash = $this -> get_now_id();
if (empty($name) or empty($hash)) {
return false;
}
// 生存时间不能大于最大生存时间
$real_ttl = $ttl <= $this -> max_life_time ? $ttl : $this -> max_life_time;
$eff_end = time() + $real_ttl;
$cache_data = array(
'data' => $value,
'ttl' => $eff_end,
);
$key = $this -> get_cache_key($name);
$json_data = json_encode($cache_data);
try {
$redis = $this -> redis -> get_handler();
$ret = $redis -> hSet($hash, $key, $json_data);
}catch(\RedisException $e) {
return false;
}
if ($ret === false) return $ret;
$this -> renew();
return true;
}
/**
* 检测cookie_id是否已经被初始化
*
* @access public
* @return boolean
*/
public function check_id_exists() {
if (isset($_COOKIE[$this -> id_client_var])) {
return true;
}
return false;
}
/**
* 删除指定名称的cookie变量
*
* @access public
* @param string $name 变量名
* @return boolean
*/
public function delete($name='') {
$name = strval($name);
$hash = $this -> get_now_id();
if (empty($name) or empty($hash)) {
return false;
}
$key = $this -> get_cache_key($name);
try {
$redis = $this -> redis -> get_handler();
$ret = $redis -> hDel($hash, $key);
}catch(\RedisException $e) {
return false;
}
return $ret;
}
/**
* 删除该cookie_id下的全部数据
*
* @access public
* @return boolean
*/
public function destory() {
$hash = $this -> get_now_id();
if (empty($hash)) return false;
$this -> redis -> delete($hash);
$this -> _cookie_id = null;
setcookie($this -> id_client_var, '', time() - 3600, '/', $this -> id_client_host, false, true);
return true;
}
/**
* 获取或构造cookie_id(不存在时)
*
* @access private
* @return string
*/
private function get_id() {
if (!empty($this -> _cookie_id)) {
return $this -> _cookie_id;
}
 
if (isset($_COOKIE[$this -> id_client_var])) {
$this -> _cookie_id = $_COOKIE[$this -> id_client_var];
}else {
$this -> _cookie_id = $this -> create_id();
//保存cookie_id到客户端
$this -> save_id();
}
return $this -> _cookie_id;
}
/**
* 保存rcookie_id到客户端
*
* @access public
* @return void
*/
private function save_id() {
setcookie($this -> id_client_var, $this -> _cookie_id, time() + $this -> id_valid_time, '/', $this -> id_client_host, false, true);
}
/**
* 刷新cookie_id的生存时间
*
* @access private
* @return boolean
*/
private function renew() {
$hash = $this -> get_now_id();
if (empty($hash)) return false;
$ret = $this -> redis -> expire($hash, $this -> max_life_time);
return $ret;
}
/**
* 生成新的cookie_id
*
* @access private
* @return string
*/
private function create_id() {
$time = time();
$uid = uniqid($this -> key_preffix, true);
$rand = get_rand_str(3);
$key_str = "rcookie_id:uid:{$uid}:time:{$time}:rand:{$rand}";
$key = sha1($key_str);
return $key;
}
/**
* 获取redis缓存变量名
*
* @access private
* @param string $str 用作生成缓存变量的字符串
* @return string
*/
private function get_cache_key($str) {
$key = md5($str);
return $key;
}
}

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

  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. .NET Core2.0+MVC 用Redis/Memory+cookie实现的sso单点登录

    之前发布过使用session+cookie实现的单点登录,博主个人用的很不舒服,为什么呢,博主自己测试的时候,通过修改host的方法,在本机发布了三个站点,但是,经过测试,发现,三个站点使用的sess ...

  4. 用redis和cookie做单用户登录

    因为公司的项目需要用到单用户登录,于是今天用redis和cookie给系统添加了单用户登录功能,再次简单记录一下. 单用户登录是为了防止同一账户在不同电脑和不同浏览器里面同时登录.所以我这边的思路是: ...

  5. springboot项目:登录 登录aop拦截 使用Redis与cookie 进行设置获取清除操作

    登录.登出: 第一步:在pom文件中引入依赖 <dependency> <groupId>org.springframework.boot</groupId> &l ...

  6. 使用redis接管session

    class RedisSession { // 默认配置名称(使用load_config加载) private $_default_config_path = 'package/cache/redis ...

  7. Yii2 redis与cache

    原文地址:http://www.myexception.cn/php/1974979.html composer require yiisoft/yii2-redis 安装后使用超简单,打开 comm ...

  8. Nginx+IIS+Redis 处理Session共享问题 1

    最近遇到一个棘手的问题,微信公众平台的前端站点session老是丢失,我们是走的微信网页授权,授权后获取用户openid,丢失后没有openid后续的操作全白搭了,因为没了openid只能判断为客户不 ...

  9. Flask系列08--Flask中flask_session, redis插件

    一.安装 1.flask_session 不想将Session的信息存放在Cookie 将Session存放在Redis Cookie中保存Session的ID flask中的session是直接将数 ...

随机推荐

  1. HBuilder的扩展插件开发暴露了一个事实:其实不能实现写一次代码实现跨平台App生成

    HBuilder的扩展插件开发,原来并不能生成单独的插件jar,而是以源码 - 类的形式进行开发,这其实就要求必须使用离线打包. 事实上,开发顺序应该是:先弄好离线打包框架,然后在AS里进行扩展插件开 ...

  2. jPlayer获取播放时间

    关于jPlayer的用法,可以参考:jPlayer 2.6.0开发者手册 http://www.jplayer.cn/developer-guide.html 视频播放例子: //视频播放 var v ...

  3. 遇到一个git branch很奇怪的问题

    最近,同事做了一个自动化的打包平台,但我发现里面的分支竟然有重复的,还有一些已经删除的branch. 比如,我已经删除了一个 test分支,在工程 game 目录下(已输入 git pull),输入: ...

  4. 什么?又是404!趣图助你理解HTTP状态码~

    HTTP状态码(一):   注释: 301—永久移动.被请求的资源已被永久移动位置: 302—请求的资源现在临时从不同的 URI 响应请求: 305—使用代理.被请求的资源必须通过指定的代理才能被访问 ...

  5. [Linux] - 网速测试命令

    Windows网速测试方法有很多,或者可以直接使用浏览器去一些网站上搜索测试即可. 在Linux中其实更容易,只需要一行命令即可搞定: curl -s https://raw.githubuserco ...

  6. JAVA获取程序(打成jar或classpath)所在目录

    一.简述 JAVA获取程序(打成jar或classpath)所在目录. 二.代码 package dearcloud.utils.context; import dearcloud.utils.Str ...

  7. Python String Formatting Best Practices

    https://imliyan.com/blogs/article/Python3.6%E6%96%B0%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%A0%BC%E5 ...

  8. 在windows命令行批量ping局域网内IP

    参考了博客园Alfred Zhao的文章<Windows平台ping测试局域网所有在用IP> 在cmd命令行运行如下命令即可: ,,) -w .%i | find "回复&quo ...

  9. SQL Server 性能优化实战系列(二)

    SQL Server datetime数据类型设计.优化误区 一.场景 在SQL Server 2005中,有一个表TestDatetime,其中Dates这个字段的数据类型是datetime,如果你 ...

  10. 分析轮子(十)- HashMap.java 之概念梳理

    注:玩的是JDK1.7版本 一:还是原来的风格,先上一下类的继承关系图,这样能够比较清楚的知道此类的相关特性 二:HashMap.java 的代码比较难看,所以,我看了几天,写的话也分开来写,这样能表 ...