2015-11-15 * * @author: Axios 2016-09-01 * * @update 2016-09-01 * 1. 增加__call魔术方法,重载当前类中方法,统一切换DB,缩减代码行数,减少类中方法互相调用时,重复切换DB * 2. 增加save_time方法,更新具有有效时间key的value,并且不重置有效时间,使用方式: DI()->redis->save_time($key, $value,$dbname); * 3. 增加counter_forever方法,永久计数器,每次调用递增1,使用方式: DI()->redis->counter_forever($key,$dbname); * 4. 增加counter_time_create方法,创建临时计数器,每次调用重置计数器和有效时间,使用方式: DI()->redis->counter_time_create($key,$expire,$dbname); * 5. 增加counter_time_update方法,更新临时计数器,每次调用递增1,使用方式: DI()->redis->counter_time_update($key,$dbname); * 6. 修复一处bug,get_time_ttl方法中,$this->unformatValue($value)修改为$value。修改前,调用此方法,会一直回调false * */ class Redis_Lite extends PhalApi_Cache_Redis{ private $db_old; /** * 重载方法,统一切换DB * * @param $name * @param $arguments * @return mixed * * @author: Axios 2016-09-01 */ public function __call($name, $arguments) { $last = count($arguments)-1; $dbname = $arguments[$last]; $this->switchDB($dbname); unset($arguments[$last]); $arguments = empty($arguments)? array():$arguments; return call_user_func_array(array($this,$name),$arguments); } //---------------------------------------------------string类型------------------------------------------------- /** * 将value 的值赋值给key,生存时间为永久 并根据名称自动切换库 */ protected function set_forever($key, $value){ return $this->redis->set($this->formatKey($key), $this->formatValue($value)); } /** * 获取value 并根据名称自动切换库 */ protected function get_forever($key){ $value = $this->redis->get($this->formatKey($key)); return $value !== FALSE ? $this->unformatValue($value) : NULL; } /** * 存入一个有实效性的键值队 */ protected function set_time($key, $value, $expire = 600){ return $this->redis->setex($this->formatKey($key), $expire, $this->formatValue($value)); } /** * 更新具有有效时间key的value,不重置有效时间 * @author Axios */ protected function save_time($key, $value) { if($this->get_exists($key)){ $ttl = $this->get_time_ttl($key); return $this->set_time($key,$value,$ttl); } return NULL; } /** * 统一get/set方法,对于set_Time使用get_Time */ protected function get_time($key){ $value = $this->redis->get($this->formatKey($key)); return $value !== FALSE ? $this->unformatValue($value) : NULL; } /** * 得到一个key的生存时间 */ protected function get_time_ttl($key){ $value = $this->redis->ttl($this->formatKey($key)); return $value !== FALSE ? $value : NULL; } /** * 批量插入k-v,请求的v需要是一个数组 如下格式 * array('key0' => 'value0', 'key1' => 'value1') */ protected function set_list($value){ $data = array(); foreach($value as $k => $v){ $data[$this->formatKey($k)] = $this->formatValue($v); } return $this->redis->mset($data); } /** * 批量获取k-v,请求的k需要是一个数组 */ protected function get_list($key){ $data = array(); foreach($key as $k => $v){ $data[] = $this->formatKey($v); } $rs = $this->redis->mget($data); foreach($rs as $k => $v){ $rs[$k] = $this->unformatValue($v); } return $rs; } /** * 判断key是否存在。存在 true 不在 false */ protected function get_exists($key){ return $this->redis->exists($this->formatKey($key)); } /** * 返回原来key中的值,并将value写入key */ protected function get_getSet($key, $value){ $value = $this->redis->getSet($this->formatKey($key), $this->formatValue($value)); return $value !== FALSE ? $this->unformatValue($value) : NULL; } /** * string,名称为key的string的值在后面加上value */ protected function set_append($key, $value){ return $this->redis->append($this->formatKey($key), $this->formatValue($value)); } /** * 返回原来key中的值,并将value写入key */ protected function get_strlen($key){ return $this->redis->strlen($this->formatKey($key)); } /** * 自动增长 * value为自增长的值默认1 */ protected function get_incr($key, $value = 1){ return $this->redis->incr($this->formatKey($key), $value); } /** * 自动减少 * value为自减少的值默认1 */ protected function get_decr($key, $value = 1){ return $this->redis->decr($this->formatKey($key), $value); } //------------------------------------------------List类型------------------------------------------------- /** * 写入队列左边 并根据名称自动切换库 */ protected function set_lPush($key, $value){ return $this->redis->lPush($this->formatKey($key), $this->formatValue($value)); } /** * 写入队列左边 如果value已经存在,则不添加 并根据名称自动切换库 */ protected function set_lPushx($key, $value){ return $this->redis->lPushx($this->formatKey($key), $this->formatValue($value)); } /** * 写入队列右边 并根据名称自动切换库 */ protected function set_rPush($key, $value){ return $this->redis->rPush($this->formatKey($key), $this->formatValue($value)); } /** * 写入队列右边 如果value已经存在,则不添加 并根据名称自动切换库 */ protected function set_rPushx($key, $value){ return $this->redis->rPushx($this->formatKey($key), $this->formatValue($value)); } /** * 读取队列左边 */ protected function get_lPop($key){ $value = $this->redis->lPop($this->formatKey($key)); return $value != FALSE ? $this->unformatValue($value) : NULL; } /** * 读取队列右边 */ protected function get_rPop($key){ $value = $this->redis->rPop($this->formatKey($key)); return $value != FALSE ? $this->unformatValue($value) : NULL; } /** * 读取队列左边 如果没有读取到阻塞一定时间 并根据名称自动切换库 */ protected function get_blPop($key){ $value = $this->redis->blPop($this->formatKey($key), DI()->config->get('app.redis.blocking')); return $value != FALSE ? $this->unformatValue($value[1]) : NULL; } /** * 读取队列右边 如果没有读取到阻塞一定时间 并根据名称自动切换库 */ protected function get_brPop($key){ $value = $this->redis->brPop($this->formatKey($key), DI()->config->get('app.redis.blocking')); return $value != FALSE ? $this->unformatValue($value[1]) : NULL; } /** * 名称为key的list有多少个元素 */ protected function get_lSize($key){ return $this->redis->lSize($this->formatKey($key)); } /** * 返回名称为key的list中指定位置的元素 */ protected function set_lSet($key, $index, $value){ return $this->redis->lSet($this->formatKey($key), $index, $this->formatValue($value)); } /** * 返回名称为key的list中指定位置的元素 */ protected function get_lGet($key, $index){ $value = $this->redis->lGet($this->formatKey($key), $index); return $value != FALSE ? $this->unformatValue($value[1]) : NULL; } /** * 返回名称为key的list中start至end之间的元素(end为 -1 ,返回所有) */ protected function get_lRange($key, $start, $end){ $rs = $this->redis->lRange($this->formatKey($key), $start, $end); foreach($rs as $k => $v){ $rs[$k] = $this->unformatValue($v); } return $rs; } /** * 截取名称为key的list,保留start至end之间的元素 */ protected function get_lTrim($key, $start, $end){ $rs = $this->redis->lTrim($this->formatKey($key), $start, $end); foreach($rs as $k => $v){ $rs[$k] = $this->unformatValue($v); } return $rs; } //未实现 lRem lInsert rpoplpush //----------------------------------------------------set类型--------------------------------------------------- //----------------------------------------------------zset类型--------------------------------------------------- //----------------------------------------------------Hash类型--------------------------------------------------- //----------------------------------------------------通用方法--------------------------------------------------- /** * 永久计数器,回调当前计数 * @author Axios */ public function counter_forever($key,$dbname=0){ $this->switchDB($dbname); if($this->get_exists($key)){ $count = $this->get_forever($key); $count++; $this->set_forever($key,$count); }else{ $count = 1; $this->set_forever($key,$count); } return $count; } /** * 创建具有有效时间的计数器,回调当前计数,单位毫秒ms * @author Axios */ public function counter_time_create($key,$expire = 1000,$dbname=0){ $this->switchDB($dbname); $count = 1; $this->set_time($key,$count,$expire); $this->redis->pSetEx($this->formatKey($key), $expire, $this->formatValue($count)); return $count; } /** * 更新具有有效时间的计数器,回调当前计数 * @author Axios */ public function counter_time_update($key,$dbname=0){ $this->switchDB($dbname); if($this->get_exists($key)){ $count = $this->get_time($key); $count++; $expire = $this->redis->pttl($this->formatKey($key)); $this->set_time($key,$count,$expire); return $count; } return false; } /** * 设定一个key的活动时间(s) */ protected function setTimeout($key, $time = 600){ return $this->redis->setTimeout($key, $time); } /** * 返回key的类型值 */ protected function type($key){ return $this->redis->type($key); } /** * key存活到一个unix时间戳时间 */ protected function expireAt($key, $time = 600){ return $this->redis->expireAt($key, $time); } /** * 随机返回key空间的一个key */ public function randomKey(){ return $this->redis->randomKey(); } /** * 返回满足给定pattern的所有key */ protected function keys($key, $pattern){ return $this->redis->keys($key, $pattern); } /** * 查看现在数据库有多少key */ protected function dbSize(){ return $this->redis->dbSize(); } /** * 转移一个key到另外一个数据库 */ protected function move($key, $db){ $arr = DI()->config->get('app.redis.DB'); $rs = isset($arr[$db]) ? $arr[$db] : $db; return $this->redis->move($key, $rs); } /** * 给key重命名 */ protected function rename($key, $key2){ return $this->redis->rename($key, $key2); } /** * 给key重命名 如果重新命名的名字已经存在,不会替换成功 */ protected function renameNx($key, $key2){ return $this->redis->renameNx($key, $key2); } /** * 删除键值 并根据名称自动切换库(对所有通用) */ protected function del($key){ return $this->redis->del($this->formatKey($key)); } /** * 返回redis的版本信息等详情 */ public function info(){ return $this->redis->info(); } /** * 切换DB并且获得操作实例 */ public function get_redis(){ return $this->redis; } /** * 查看连接状态 */ public function ping(){ return $this->redis->ping(); } /** * 内部切换Redis-DB 如果已经在某个DB上则不再切换 */ protected function switchDB($name){ $arr = DI()->config->get('app.redis.DB'); if(is_int($name)){ $db = $name; }else{ $db = isset($arr[$name]) ? $arr[$name] : 0; } if($this->db_old != $db){ $this->redis->select($db); $this->db_old = $db; } } //-------------------------------------------------------谨慎使用------------------------------------------------ /** * 清空当前数据库 */ protected function flushDB(){ return $this->redis->flushDB(); } /** * 清空所有数据库 */ public function flushAll(){ return $this->redis->flushAll(); } /** * 选择从服务器 */ public function slaveof($host, $port){ return $this->redis->slaveof($host, $port); } /** * 将数据同步保存到磁盘 */ public function save(){ return $this->redis->save(); } /** * 将数据异步保存到磁盘 */ public function bgsave(){ return $this->redis->bgsave(); } /** * 返回上次成功将数据保存到磁盘的Unix时戳 */ public function lastSave(){ return $this->redis->lastSave(); } /** * 使用aof来进行数据库持久化 */ protected function bgrewriteaof(){ return $this->redis->bgrewriteaof(); } }