* 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() // }