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;
}
}