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. Docker卸载高版本重装低版本后启动提示:driver not supported

    解决方法: mv /var/lib/docker /var/lib/docker.old 其实就是docker镜像文件夹目录作怪,新版本的目录无法与旧版本目录相兼容. 不过建议降级的用户这样操作: y ...

  2. TOML简介 (转) TOML的由来

    TOML的由来 配置文件的使用由来已久,从.ini.XML.JSON.YAML再到TOML,语言的表达能力越来越强,同时书写便捷性也在不断提升. TOML是前GitHub CEO, Tom Prest ...

  3. Cocos Creator学习笔记

    1.动态加载图片 cc.Class({ extends: cc.Component, properties: { label: { default: null, type: cc.Label }, l ...

  4. Unsupervised pre-training

    如图所示: 假设你想要解决一个复杂的任务,你没有太多的标记的训练数据,但不幸的是,你不能找到一个类似的任务训练模型. 不要失去所有希望! 首先,你当然应该尝试收集更多的有标签的训练数据,但是如果这太难 ...

  5. shell编程学习笔记(十一):Shell中的while/until循环

    shell中也可以实现类似java的while循环 while循环是指满足条件时,进行循环 示例: #! /bin/sh index=10 while [ $index -gt 0 ] do inde ...

  6. iOS 随机数获取

    //获取一个32位随机数 static const char _randomStr[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv ...

  7. H5调用本地摄像头[转]

    http://www.cnblogs.com/GoodPingGe/p/4726126.html <!DOCTYPE html><html><head lang=&quo ...

  8. 对Faster R-CNN的理解(1)

    目标检测是一种基于目标几何和统计特征的图像分割,最新的进展一般是通过R-CNN(基于区域的卷积神经网络)来实现的,其中最重要的方法之一是Faster R-CNN. 1. 总体结构 Faster R-C ...

  9. 使用h5py操作hdf5文件

    HDF(Hierarchical Data Format)指一种为存储和处理大容量科学数据设计的文件格式及相应库文件.HDF 最早由美国国家超级计算应用中心 NCSA 开发,目前在非盈利组织 HDF ...

  10. DES算法原理完整版

    1.所需参数 key:8个字节共64位的工作密钥 data:8个字节共64位的需要被加密或被解密的数据 mode:DES工作方式,加密或者解密 2.初始置换 DES算法使用64位的密钥key将64位的 ...