* 1.0.4 取消公共基类CMemBase,后面可能不太会用到memcache(d)了. gwang 2020年11月23日
* 1.0.3 扩展list相关api的操作方法, 针对values统一做json编解码处理.
* 整理其他数据结构的操作方法, normal/hash/list api内部做json编解码处理,
* set/zset value 默认不做json编解码处理, 针对set/zset的value,不推荐写入太大或复杂的数据.
* gwang 2017年4月28日
* 1.0.2 扩充特有数据结构的操作方法, gwang 2016.4.21
* 1.0.1 扩充了事务的使用方法.开发竞争类业务,圣树争夺战, gwang 2016.3.21
* 1.0.0 pguan,基础功能, 方法与memcache看齐.
*/
class CRedisUtil {
// public $keyDic = null;
//
static $caller_counter = array();
/**
* 调用统计
*/
public static function AddCallCount() {
self::$caller_counter[] = DebugHelper::get_call_stack(3, 2, true);
}
//
/**
*
* @var ClientInterface
*/
public $redis = null;
/**
* 自动回收
*/
function __destruct() {
$this->close();
}
private static function debug() {
if (defined('Redis_Debug') && Redis_Debug) {
// DebugHelper::debug(DebugHelper::get_call_stack());
self::AddCallCount();
}
}
//
/**
* 添加一个值
* @param string $key
* @param string $value
* @param int $ts=0 此值无效
* @return true 成功, false 失败,此key已经存在
*/
public function add($key, $value, $ts = 0) {
self::debug();
return $this->setnx($key, JsonUtil::encode($value));
}
/**
* 复制一个变量到另一个key
* @param string $surKey 源数据的key
* @param string $desKey 目的数据的key
*/
public function copy($surKey, $desKey) {
self::debug();
return $this->set($desKey, $this->get($surKey));
}
/**
* 一次取多个值
* @param array(string) $keys
* @return array
*/
public function getMulti($keys) {
self::debug();
// var_dump($keys);
return $this->mget($keys);
}
/**
* 设置多个值
* @param dic $dict [{"key":value},{"key":value},....]
* @return true 永远成功
*/
public function setMutlti($dict) {
self::debug();
$params = array();
foreach ($dict as $key => $val) {
$params[$key] = is_string($val) ? $val : JsonUtil::encode($val);
}
if (count($params) <= 0) {
return TRUE;
}
$this->mset($params);
return true;
}
/**
* 替换某个值
* @param string $key
* @param string $value
* @param int $ts
* @return boolean true 成功,false 失败
*/
public function replace($key, $value, $ts = 0) {
self::debug();
$ret = $this->redis->setex($key, $value, $ts);
if (strtolower($ret) == "ok") {
return true;
}
$this->logErr("replace" . $ret);
return false;
}
/**
* 不经过jsonencode直接存储
* @deprecated since version 20160413113950 经过自己考察json_encode对数据的影响并不存在
* @param type $key
* @return any
*/
public function getWithoutJson($key) {
self::debug();
return $this->redis->get($key);
}
/**
* 不经过jsondecode直接返回
* @deprecated since version 20160413113950 经过自己考察json_encode对数据的影响并不存在
* @param string $key
* @param string $value
* @param int $ts
* @return boolean
*/
public function setWithoutJson($key, $value, $ts = 0) {
self::debug();
$ret = $this->redis->set($key, $value, $ts);
if (strtolower($ret) == "ok") {
return true;
}
$this->logErr("set" . $ret);
return false;
}
/**
* 输出日志
* @param mixed $msg
*/
private function logErr($msg) {
CLog::err($msg, "Redis Err:");
}
/**
* 连接
* @param string $host
* @param string $port
* @param string $pwd
* @param string $db 数据库, 不建议输入参数, 如果是购买云实例只有一个db.
* @return \CRedisUtil
*/
public function conn($host, $port, $pwd = "", $db = 0) {
// DebugHelper::print_stack_trace();
// $this->redis = new \Predis\Client(array(
// $this->redis = new \Redis();
// $this->redis->connect('127.0.0.1', 6379);
// $this->redis->auth($pwd);
$this->redis = new \Predis\Client(array(
'scheme' => 'tcp',
'host' => $host,
'port' => $port,
'password' => $pwd,
));
if ($db != 0) {
$this->redis->select($db);
}
// $this->keyDic = new \stdClass();
return $this;
}
/**
* 关闭连接
*/
public function close() {
$this->redis->quit();
}
/**
* 获取指定键值
* @param string $key
* @return any json_decode($result)
*/
public function get($key) {
self::debug();
$result = $this->redis->get($key);
if (!$result || $result == "" || $result == null) {
return null;
}
// $this->keyDic->$key = $result;
return JsonUtil::decode($result);
}
/**
* 将字符串值 $val 关联到 key
* @param string $key
* @param any $value
* @param int $ts default(0) 过期时间(单位秒)
* @return boolean 成功true,失败false
*/
public function set($key, $value, $ts = 0) {
self::debug();
if ($value === null || $value === "") { # 这里必须用全等符号
return false;
}
if (is_string($value)) { # 使用json序列化后存储
$val = $value;
} else {
$val = JsonUtil::encode($value);
}
if ($ts > 0) { # 将会设置TTL 到期删除 ps: replaced by gwang 增加过期时间
$ret = $this->redis->setex($key, $ts, $val);
} else { # 0:永不过期,如果原来有TTL将会清除TTL.
$ret = $this->redis->set($key, $val);
}
if ("OK" != $ret) {
$this->logErr("Set:" . $ret);
return false;
}
return true;
}
/**
* 安全的写入操作
* @deprecated since version 1.0 云平台暂时不支持
* @param string $key
* @param any $value
* @return boolean 成功true,失败false
*/
public function cas($key, $value, $ts = 0) {
if (false) { # ps. 各云平台皆不支持eval方法执行lua脚本.等开放支持的时候才是真正支持cas的时候
$castoken = $this->keyDic->$key;
# # 定义一段脚本
$script = <<redis->eval($script, 1, $key, $value); # redis 执行lua脚本
if (0 == $ret) {
return false;
}
return true;
}
// 非线程安全,原因见下
return $this->set($key, $value, $ts);
}
/**
* 删除一个指定键值
* @param string $key
* @return int 删除键的个数
*/
public function delete($key) {
self::debug();
my_Assert(is_string($key), "arg key should be a string!");
$infos = array();
array_push($infos, $key);
return $this->redis->del($infos);
}
/**
* 删除一个或多个指定键值
* @param array $keys
* @return int 删除键的个数
*/
public function deleteMulti($keys) {
self::debug();
$infos = (array) $keys; # 强制转数据类型为数组
return $this->redis->del($infos);
}
//
//
//
/**
* 返回所有(一个或多个)给定 key 的值
* 如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。因此,该命令永不失败。
* @param array $keys
* @return array 一个包含所有给定 key 的值的列表
*/
private function mget($keys) {
// self::debug();
$ret = array();
if (count($keys)) {
$ctx = $this->redis->mget($keys);
$mval = count($ctx);
for ($i = 0;
$i < $mval;
$i++) {
$ret[] = JsonUtil::decode($ctx[$i]);
}
}
return $ret;
}
/**
* Add函数拥有相同效果 \n
* 将 key 的值设为 value ,当且仅当 key 不存在。
* 若给定的 key 已经存在,则不做任何动作。
* @param type $key
* @param type $val
* @return boolean 成功true,失败false
*/
private function setnx($key, $val) {
self::debug();
$ret = $this->redis->setnx($key, $val);
// 成功返回1, 失败返回0
if (1 == $ret) {
return true;
} else {
$this->logErr("setnx:" . $ret . "(值已存在)");
}
return false;
}
/**
* 同时设置一个或多个 key-value 对
* 如果某个给定 key 已经存在,那么 MSET 会用新值覆盖原来的旧值
* @param array $dict
* @return mixed
*/
private function mset($dict) {
self::debug();
return $this->redis->mset($dict);
}
/**
* 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在
* 即使只有一个给定 key 已存在, MSETNX 也会拒绝执行所有给定 key 的设置操作
*
* @param array $dict
* @return int
*/
public function msetnx($dict) {
self::debug();
$ret = $this->redis->msetnx($dict);
return $ret == 1;
}
/**
* 检测指定键值是否存在
* @param type $key
* @return boolean true 存在, false 不存在
*/
public function exists($key) {
self::debug();
return $this->redis->exists($key) == 1;
}
/**
* 将 key 中储存的数字值增一
* 如果 key 不存在,那么 key 的值会先被初始化为 0
* 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误
* 本操作的值限制在 64 位(bit)有符号数字表示之内
* @param type $key
* @return int 执行 INCR 命令之后 key 的值
*/
public function increment($key) {
self::debug();
return $this->redis->incr($key);
}
/**
* 将 key 中储存的数字值增加 一个int值
* 如果 key 不存在,那么 key 的值会先被初始化为 0
* 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误
* 本操作的值限制在 64 位(bit)有符号数字表示之内
* @param string $key
* @param int $i 增加的值
* @return int 执行 INCR 命令之后 key 的值
*/
public function incrby($key, $i) {
self::debug();
return $this->redis->incrby($key, $i);
}
//
//
//======================== 以下部分 added by gwang at 2016-4-14 15:17:25 =================
//
/**
* Server功能,看服务器是否连通
* @return boolean true连通正常
*/
public function ping() {
$ret = $this->redis->ping();
if ($ret == "PONG") {
return true;
}
$this->logErr("ping:" . $ret);
return false;
}
/**
* 对数组进行json编码
* @param array $values
* @return array
*/
static private function json_encode_arr($values) {
$arr = array();
if (is_array($values)) {
$arr = array_map(function ($v) {
return JsonUtil::encode($v);
}, $values);
} else {
$arr[] = JsonUtil::encode($values);
}
return $arr;
}
/**
* 对数组进行json解码
* @param array $values
* @return array
*/
static private function json_decode_arr(array $values) {
$arr = array();
if (is_array($values)) {
$arr = array_map(function ($v) {
return JsonUtil::decode($v);
}, $values);
} else {
$arr[] = JsonUtil::decode($values);
}
return $arr;
}
//
//
//
/**
* 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
* @param string $key
*/
public function watch($key) {
$this->redis->watch($key);
}
/**
* 取消监视
*/
public function unwatch() {
$this->redis->unwatch();
}
/**
* 开启事务
*/
public function multi() {
$this->redis->multi();
}
/**
* 执行事务
* @return type 事务块内所有命令的返回值,按命令执行的先后顺序排列。当操作被打断时,返回空值 nil 。
*/
public function exec() {
return $this->redis->exec();
}
//
//
// == ↓ 下面是Redis独有的数据类型操作 ↓ ==
//
//
/**
* 集合(set) - 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
* 集合不存在时将会创建集合
* @param string $key
* @param string[] $members (mixed is ok, i will transmit it.)
* @return int
* @expectedException type not set error
*/
public function sadd($key, $members) {
self::debug();
if (!is_array($members)) { # 防御: 参数不为数组
if (!is_string($members)) { # 防御: 参数不为字符串
$members = JsonUtil::encode($members);
}
$members = array($members); # 转为字符串数组
}
return $this->redis->sadd($key, $members);
}
/**
* 集合(set) - 将一个或多个 member 元素从集合 key 当中移除
* 集合不存在时将会创建集合
* @param string $key
* @param string[] $members
* @return int
* @expectedException type not set error
*/
public function sremove($key, $members) {
self::debug();
return $this->redis->srem($key, $members);
}
/**
* 集合(set) - 返回集合 key 的基数(集合中元素的数量)。
* @param strig $key
* @return int
*/
public function scard($key) {
self::debug();
return $this->redis->scard($key);
}
/**
* 集合(set) - 等效于scard: 返回集合 key 的基数(集合中元素的数量)。
* @param string $key
* @return int
*
*/
public function slen($key) {
self::debug();
return $this->scard($key);
}
/**
* 集合(set) - 判断某个元素是否属于集合
* @param string $key
* @param string $member
* @return bool
*/
public function sismember($key, $member) {
self::debug();
return $this->redis->sismember($key, $member) == 1;
}
/**
* 集合(set) - 返回集合 key 中的所有成员。
* @param type $key
* @return array 不存在的key视为空集合
*/
public function smembers($key) {
self::debug();
return $this->redis->smembers($key);
}
/**
* 集合(set) - 如果命令执行时,只提供了 key 参数,那么返回集合中的10个随机元素。
* 如果 count 为正数,且小于集合基数,那么命令返回一个包含 count 个元素的数组,数组中的元素各不相同。如果 count 大于等于集合基数,那么返回整个集合。
* 如果 count 为负数,那么命令返回一个数组,数组中的元素可能会重复出现多次,而数组的长度为 count 的绝对值。
* @param string $key
* @param int $count =10
* @return array
*/
public function srandmember($key, $count = 10) {
self::debug();
return $this->redis->srandmember($key, $count);
}
//
//
//
/**
* 哈希表 - 删除 字段
* @param string $key
* @param array $fields
* @return int 删除的字段的数量
*/
public function hdel($key, $fields) {
self::debug();
return $this->redis->hdel($key, $fields);
}
/**
* 哈希表 - 判断field是否存在
* @param string $key
* @param string $field
* @return boolean true=存在,false 找不到
*/
public function hexists($key, $field) {
self::debug();
return $this->redis->hexists($key, $field) == 1;
}
/**
* 哈希表 - 获取字段
* @param string $key
* @param string $field 字段名
* @return mixed json_decoded object
*/
public function hget($key, $field) {
self::debug();
$ret = $this->redis->hget($key, $field);
return JsonUtil::decode($ret);
}
/**
* 哈希表 - 获取所有字段
* @param string $key
* @return stdclass/associate_array (适用箭头取变量写法)
*/
public function hgetall($key) {
self::debug();
$ret = ArrayInit();
$arr = $this->redis->hgetall($key);
foreach ($arr as $k => $v) {
$ret[$k] = JsonUtil::decode($v);
}
// 转为关联数组({})再返回, 方便代码中使用箭头写法
return JsonUtil::decode(JsonUtil::encode($ret));
}
/**
* 哈希表 - 获取表中字段数量
* @param string $key
* @return int
*/
public function hlen($key) {
self::debug();
return $this->redis->hlen($key);
}
/**
* 哈希表 - 同时获取多个字段
* @param string $key
* @param array $fields
* @return Array
*/
public function hmget($key, $fields) {
self::debug();
$ret = ArrayInit();
if (is_array($fields) && count($fields) > 0) {
$arr = $this->redis->hmget($key, $fields);
foreach ($arr as $k => $v) {
$ret[$k] = JsonUtil::decode($v);
}
}
// 转为关联数组({})再返回, 方便代码中使用箭头写法
return JsonUtil::decode(JsonUtil::encode($ret));
}
/**
* 哈希表 - 同时设置多个字段的值
* @param string $key
* @param assoc_array $dictionary
* @return boolean true成功
*/
public function hmset($key, $dictionary) {
self::debug();
$newdic = ArrayInit();
foreach ($dictionary as $k => $v) {
$newdic[$k] = JsonUtil::encode($v);
}
$ret = $this->redis->hmset($key, $newdic);
if (strtolower($ret) == 'ok') {
return true;
}
return false;
}
/**
* 哈希表 - 同时设置多个字段的值(带Not Changed校验)
* @param string $key
* @param HashSaver $dic (要包含$stVer字段用以校验)
* @return boolean 写入是否成功
*/
public function hmset_Cas(string $key, HashSaver $dic) {
# # 定义一段脚本
static $script = <<stVer;
// CLog::err($dic->toString());
// var_dump($dic->toString());
$ret = $this->redis->eval($script, 2, $key, $castoken, $casVer, $dic->toString()); # redis 执行lua脚本
// CLog::err($dic->toString());
if (0 == $ret) {
return false;
}
} catch (\Exception $e) {
CLog::err($e->getMessage());
return false;
}
return true;
}
/**
* 哈希表 - 设置或新建一个字段的值
* @param string $key
* @param string $field
* @param $mixed $value
* @return int 0 覆盖旧值, 1 新建字段
*/
public function hset($key, $field, $value) {
self::debug();
return $this->redis->hset($key, $field, JsonUtil::encode($value));
}
/**
* 哈希表 - 增加一个新的field,已经存在则放弃操作返回false
* @param string $key
* @param string $field
* @param string $value
* @return boolean true成功
*/
public function hsetnx($key, $field, $value) {
self::debug();
return $this->redis->hsetnx($key, $field, JsonUtil::encode($value)) == 1;
}
/**
* 哈希表 - 按字段赠加 int值
* @param string $key
* @param string $field
* @param int $increment
* @return int
*/
public function hincrby($key, $field, $increment) {
self::debug();
return $this->redis->hincrby($key, $field, $increment);
}
/**
* 哈希表 - 按字段增加 float值
* @param string $key
* @param string $field
* @param string $increment float值用string
* @return string 用string存float值
*/
public function hincrbyfloat($key, $field, $increment) {
self::debug();
return $this->redis->hincrbyfloat($key, $field, $increment);
}
/**
* @param string $key
* @return array
*/
public function hkeys($key) {
self::debug();
return $this->redis->hkeys($key);
}
// * @method array hscan($key, $cursor, array $options = null)
// * @method array hvals($key)
//
//
//
//
//
/**
* 链表 - 阻塞弹出, 当列表中没有元素的时候,命令会阻塞,直到等待超时或者有元素被添加到列表中.
* @param array $keys 可以指定多个数组
* @param int $timeout
* @return array
*/
public function blpop(array $keys, $timeout) {
self::debug();
$arr = $this->redis->blpop($keys, $timeout);
$arr[1] = JsonUtil::decode($arr[1]); // 对value进行解包
return $arr;
}
/**
* 链表 - 阻塞队尾弹出, 当列表中没有元素的时候,命令会阻塞,直到等待超时或者有元素被添加到列表中.
* @return array
*/
public function brpop(array $keys, $timeout) {
self::debug();
$arr = $this->redis->brpop($keys, $timeout);
$arr[1] = JsonUtil::decode($arr[1]);
return $arr;
}
/**
* 链表 - 阻塞版的 队尾弹出插入到队首. 本操作是原子的.
*
* @return array 假如在指定时间内没有任何元素被弹出,则返回一个 nil 和等待时长。
* 反之,返回一个含有两个元素的列表,第一个元素是被弹出元素的值,第二个元素是等待时长。
*/
public function brpoplpush($source, $destination, $timeout) {
self::debug();
$arr = $this->redis > brpoplpush($source, $destination, $timeout);
$arr[0] = JsonUtil::decode($arr[0]);
return $arr;
}
//
//
/**
* 链表 - 返回下标为index的元素
* @return string
*/
public function lindex($key, $index) {
self::debug();
$a = $this->redis->lindex($key, $index);
return JsonUtil::decode($a);
}
/**
* 链表 - 返回 链表key的长度
* @return int
* @param type $key
*/
public function llen($key) {
self::debug();
return $this->redis->llen($key);
}
/**
* 链表 - 移除并返回链表的队首元素.
* @return string
* @param type $key
*/
public function lpop($key) {
self::debug();
$a = $this->redis->lpop($key);
return JsonUtil::decode($a);
}
/**
* 链表 - 向链表插入一个或多个值,链表不存在时创建链表并插入元素
* @return int key存在却不是链表类型时返回一个错误.
* @param type $key
* @param array $values
*/
public function lpush($key, $values) {
self::debug();
$arr = self::json_encode_arr($values);
return $this->redis->lpush($key, $arr);
}
/**
* 链表 - 取链表中指定下标区间的元素
* @return array
* @param string $key
* @param int $start
* @param int $stop
*/
public function lrange($key, $start, $stop) {
self::debug();
$values = $this->redis->lrange($key, $start, $stop);
return self::json_decode_arr($values);
}
/**
* 链表 - 移除链表中 count 个值为 value的元素.
* @return int
* @param string $key
* @param int $count
* @param string $value
*/
public function lrem($key, $count, $value) {
self::debug();
return $this->redis->lrem($key, $count, JsonUtil::encode($value));
}
/**
* 链表 - 将链表中下标为index的 元素设置为value
* @return mixed
*
* @param type $key
* @param type $index
* @param type $value
*/
public function lset($key, $index, $value) {
self::debug();
return $this->redis->lset($key, $index, JsonUtil::encode($value));
}
/**
* 链表 - 对链表进行修剪, 让链表只保留指定下标区间的元素,其余元素删除
* @return bool true 成功, false 失败
* @param string $key
* @param int $start
* @param int $stop
*/
public function ltrim($key, $start, $stop) {
self::debug();
// return mixed: ok or fails
$ret = $this->redis->ltrim($key, $start, $stop);
if (strtolower($ret) == 'ok') {
return true;
}
return false;
}
/**
* 链表 - 从链表右侧(尾部)弹出一个元素,并返回该元素
* @param string $key
* @return string 列表的尾元素。当 key 不存在时,返回 nil
*/
public function rpop($key) {
self::debug();
return JsonUtil::decode($this->redis->rpop($key));
}
/**
* 将一个或多个值 value 插入到列表 key 的表尾(最右边)。
* @param string $key
* @param array $values
* @return int
*/
public function rpush($key, array $values) {
self::debug();
$arr = self::json_encode_arr($values);
return $this->redis->rpush($key, $arr);
}
//
// /**
// * 链表 - 向链表中插入一个或多个值,链表不存在时,什么也不做.
// * @return int
// * @param type $key
// * @param type $value
// */
// public function lpushx($key, $value)
// {
// return $this->redis->lpushx($key, $value);
// }
// /**
// * 链表 - 将值 value 插入到链表 key 中 , 位于pivot之前或之后
// * @return int -1:未找到pivot, 0:链表为空或者不存在.
// *
// * @param string $key 链表名称
// * @param string $whence after/before pivot之前或之后
// * @param string $pivot 插入pivot之前或之后
// * @param string $value 要插入的value
// */
// public function linsert($key, $whence, $pivot, $value)
// {
// $this->redis->linsert($key, $whence, $pivot, $value);
// }
// /**
// * 在一个原子时间内,执行以下两个动作
// * 将列表 source 中的最后一个元素(尾元素)弹出,并返回给客户端。
// * 将 source 弹出的元素插入到列表 destination ,作为 destination 列表的的头元素.
// * @return string
// */
// public function rpoplpush($source, $destination)
// {
// throw new Exception("un implemented now!");
// }
// /**
// * 将值 value 插入到列表 key 的表尾,当且仅当 key 存在并且是一个列表。
// * 和 RPUSH 命令相反,当 key 不存在时, RPUSHX 命令什么也不做。
// * @param type $key
// * @param type $value
// * @return int
// */
// public function rpushx($key, $value)
// {
// throw new Exception("un implemented now!");
// }
//
//
//
/**
* 有序集合 - 添加或更新元素 对于zset类型不建议写入太长, 太复杂的value
* @param string $key
* @param array $membersAndScoresDictionary array( 'value'=>score,'value'=>score,...), score可以是int或float
* @return int 新增元素数量,不包含更新的元素
*/
public function zadd($key, $membersAndScoresDictionary) {
self::debug();
return $this->redis->zadd($key, $membersAndScoresDictionary);
}
/**
* 有序集合 - 给某个元素增加积分
* @param string $key
* @param string $member
* @param int $increment
* @return string
*/
public function zincrby($key, $member, $increment = 1) {
self::debug();
return $this->redis->zincrby($key, $increment, $member);
}
/**
* 有序集合 - 元素数量
* @param string $key
* @return int
*/
public function zlen($key) {
self::debug();
return $this->redis->zcard($key);
}
/**
* 有序集合 - 统计某区间元素数量
* @param string $key
* @param int/float $min 最低分
* @param int/float $max 最高分
* @return int
*/
public function zcount($key, $min, $max) {
self::debug();
return $this->redis->zcount($key, $min, $max);
}
/**
* 有序集合 - 获取集合指定区间内的成员, 第一个成员从0开始
* @param string $key
* @param int $start
* @param int $stop Ps.以 -1 表示最后一个成员, -2 表示倒数第二个成员
* @param boolean $withScore 返回值中是否带score字段
* @return array (index=>member) or assoc_array (member=>score)
*/
public function zrange($key, $start, $stop, $withScore = false) {
self::debug();
if ($withScore) {
return $this->redis->zrange($key, $start, $stop, 'WITHSCORES');
} else {
return $this->redis->zrange($key, $start, $stop);
}
if ($withScore) {
$ret = $this->redis->zrange($key, $start, $stop, 'WITHSCORES');
DebugHelper::var_dump($ret);
$ma = count($ret);
$arr = array();
for ($i = 0; $i < $ma; $i += 2) {
$arr[$ret[$i]] = $ret[$i + 1];
}
return $arr;
} else {
$ret = $this->redis->zrange($key, $start, $stop);
DebugHelper::var_dump($ret);
return $ret;
}
}
/**
*
* 有序集合 - 获取集合倒序之后,指定区间内的成员, 第一个成员从0开始
* @param string $key
* @param int $start
* @param int $stop Ps.以 -1 表示最后一个成员, -2 表示倒数第二个成员
* @param boolean $withScore 返回值中是否带score字段 default(false)
* @return array (index=>member) or assoc_array (member=>score) 用foreach(=>)取
*/
public function zrevrange($key, $start, $stop, $withScore = false) {
self::debug();
if ($withScore) {
$r = $this->redis->zrevrange($key, $start, $stop, 'WITHSCORES');
return $r;
} else {
return $this->redis->zrevrange($key, $start, $stop);
}
}
/**
*
* 有序列表 - 获取指定积分区间内的成员
* @param string $key
* @param int/float $min
* @param int/float $max
* @param boolean $withScore
* @param bool $limit 是否限制返回值大小
* @param int $offset 限制返回结果的起始位置
* @param type $count 返回结果的数量
* @return type
*/
public function zrangebyscore($key, $min, $max, $withScore = false, $limit = false, $offset = 0, $count = 10) {
self::debug();
if ($limit) {
if ($withScore) {
return $this->redis->zrangebyscore($key, $min, $max, 'WITHSCORES', "LIMIT", $offset, $count);
} else {
return $this->redis->zrangebyscore($key, $min, $max, 'LIMIT', $offset, $count);
}
} else {
if ($withScore) {
return $this->redis->zrangebyscore($key, $min, $max, 'WITHSCORES');
} else {
return $this->redis->zrangebyscore($key, $min, $max);
}
}
}
/**
*
* 有序列表 - 获取按照倒序排序后指定积分区间内的成员
* @param string $key
* @param int/float $max
* @param int/float $min
* @param boolean $withScore
* @param bool $limit 是否限制返回值大小
* @param int $offset 限制返回结果的起始位置
* @param type $count 返回结果的数量
* @return type
*/
public function zrevrangebyscore($key, $max, $min, $withScore = false, $limit = false, $offset = 0, $count = 10) {
self::debug();
if ($limit) {
if ($withScore) {
return $this->redis->zrevrangebyscore($key, $max, $min, 'WITHSCORES', "LIMIT", $offset, $count);
} else {
return $this->redis->zrevrangebyscore($key, $max, $min, 'LIMIT', $offset, $count);
}
} else {
if ($withScore) {
return $this->redis->zrevrangebyscore($key, $max, $min, 'WITHSCORES');
} else {
return $this->redis->zrevrangebyscore($key, $max, $min);
}
}
}
/**
* 有序列表 - 根据元素反查排名
* @param string $key
* @param string $member
* @return int
*/
public function zrank($key, $member) {
self::debug();
return $this->redis->zrank($key, $member);
}
/**
* 有序列表 - 查询某个成员的倒序排名
* @param string $key
* @param string $member
* @return int
*/
public function zrevrank($key, $member) {
self::debug();
return $this->redis->zrevrank($key, $member);
}
/**
* 有序列表 - 根据元素反查积分
* @param string $key
* @param string $member
* @return int/float
*/
public function zscore($key, $member) {
self::debug();
return $this->redis->zscore($key, $member);
}
/**
* 有序列表 - 移除元素
* @param string $key
* @param string $member
*/
public function zrem($key, $member) {
self::debug();
$this->redis->zrem($key, $member);
}
/**
* 有序列表 - 移除指定区间的元素
* @param string $key
* @param int $start
* @param int $stop
*/
public function zremrangebyrank($key, $start, $stop) {
self::debug();
$this->redis->zremrangebyrank($key, $start, $stop);
}
/**
* 有序列表 - 移除指定积分区间的元素.
* @param string $key
* @param int/float $min
* @param int/float $max
*/
public function zremrangebyscore($key, $min, $max) {
self::debug();
$this->redis->zremrangebyscore($key, $min, $max);
}
/**
* 有序列表 - 复制有序类表到一个新的key
* @param string $key_source 源集合
* @param string $key_new 目标集合
*/
public function zcopy($key_source, $key_new) {
self::debug();
$this->redis->zunionstore($key_new, 1, $key_source);
}
//
//
//
//
/**
* 重命名一个key(注意: 与move的区别, move是将数据迁移到其他db,rename相当于在当前db内move)
* @param type $key
* @param type $newkey
* @return boolean
*/
public function rename($key, $newkey) {
self::debug();
return $this->redis->rename($key, $newkey) == "ok";
}
/**
* 给指定的key设置/更新生存时间
* @param string $key
* @param number $seconds
* @return bool
*/
public function expire($key, $seconds) {
self::debug();
return $this->redis->expire($key, $seconds) == "ok";
}
// == end of zSet ===
// * @method string zincrby($key, $increment, $member)
// * @method int zinterstore($destination, array $keys, array $options = null)
// * @method array zrevrangebyscore($key, $min, $max, array $options = null)
// * @method int zunionstore($destination, array $keys, array $options = null)
// * @method array zscan($key, $cursor, array $options = null)
// * @method array zrangebylex($key, $start, $stop, array $options = null)
// * @method int zremrangebylex($key, $min, $max)
// === end of zSet 操作 =====
// ======= hash 操作 ======
//
// // ======== set 操作 ======
// * @method array sdiff(array $keys)
// * @method int sdiffstore($destination, array $keys)
// * @method array sinter(array $keys)
// * @method int sinterstore($destination, array $keys)
//
// * @method int smove($source, $destination, $member)
// * @method string spop($key)
// * @method array sscan($key, $cursor, array $options = null)
// * @method array sunion(array $keys)
// * @method int sunionstore($destination, array $keys)
// ======= 订阅相关api =======s
// * @method int pfadd($key, array $elements)
// * @method mixed pfmerge($destinationKey, array $sourceKeys)
// * @method int pfcount(array $keys)
// * @method mixed pubsub($subcommand, $argument)
// * @method int publish($channel, $message)
// *
// ======= 事务相关api =======
// * @method mixed discard()
public function discard() {
return $this->redis->discard();
}
// * @method array exec()
// * @method mixed multi()
// * @method mixed unwatch()
// * @method mixed watch($key)
// ======= 执行lua脚本 =======
// * @method mixed eval($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null)
// * @method mixed evalsha($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null)
// * @method mixed script($subcommand, $argument = null)
// ======= 服务器操作api ======
// * @method mixed auth($password)
// * @method string echo($message)
// * @method mixed ping($message = null)
// * @method mixed select($database)
// * @method mixed bgrewriteaof()
// * @method mixed bgsave()
//
}