// +---------------------------------------------------------------------- namespace think\cache\driver; use think\cache\Driver; /** * Redis缓存驱动,适合单机部署、有前端代理实现高可用的场景,性能最好 * 有需要在业务层实现读写分离、或者使用RedisCluster的需求,请使用Redisd驱动 * * 要求安装phpredis扩展:https://github.com/nicolasff/phpredis * * @author 尘缘 <130775@qq.com> * Modified by wuyonghong BEGIN 2019/02/19 ISSUES Redis添加有序队列支持 */ class Redis extends Driver { protected $options = [ 'host' => '127.0.0.1', 'port' => 6379, 'password' => '', 'select' => 0, 'timeout' => 0, 'expire' => 0, 'persistent' => false, 'prefix' => '', ]; /** * 构造函数 * * @param array $options 缓存参数 * * @access public */ public function __construct($options = []) { if (!extension_loaded('redis')) { throw new \BadFunctionCallException('not support: redis'); } if (!empty($options)) { $this->options = array_merge($this->options, $options); } $this->handler = new \Redis; if ($this->options['persistent']) { $this->handler->pconnect( $this->options['host'], $this->options['port'], $this->options['timeout'], 'persistent_id_'.$this->options['select'] ); } else { $this->handler->connect($this->options['host'], $this->options['port'], $this->options['timeout']); } if ('' != $this->options['password']) { $this->handler->auth($this->options['password']); } if (0 != $this->options['select']) { $this->handler->select($this->options['select']); } } /** * 判断缓存 * * @access public * * @param string $name 缓存变量名 * * @return bool */ public function has($name) { return $this->handler->exists($this->getCacheKey($name)); } /** * 读取缓存 * * @access public * * @param string $name 缓存变量名 * @param mixed $default 默认值 * * @return mixed */ public function get($name, $default = false) { $value = $this->handler->get($this->getCacheKey($name)); if (is_null($value) || false === $value) { return $default; } try { $result = 0 === strpos($value, 'think_serialize:') ? unserialize(substr($value, 16)) : $value; } catch (\Exception $e) { $result = $default; } return $result; } /** * 写入缓存 * * @access public * * @param string $name 缓存变量名 * @param mixed $value 存储数据 * @param integer|\DateTime $expire 有效时间(秒) * * @return boolean */ public function set($name, $value, $expire = null) { if (is_null($expire)) { $expire = $this->options['expire']; } if ($expire instanceof \DateTime) { $expire = $expire->getTimestamp() - time(); } if ($this->tag && !$this->has($name)) { $first = true; } $key = $this->getCacheKey($name); $value = is_scalar($value) ? $value : 'think_serialize:'.serialize($value); if ($expire) { $result = $this->handler->setex($key, $expire, $value); } else { $result = $this->handler->set($key, $value); } isset($first) && $this->setTagItem($key); return $result; } /** * 自增缓存(针对数值缓存) * * @access public * * @param string $name 缓存变量名 * @param int $step 步长 * * @return false|int */ public function inc($name, $step = 1) { $key = $this->getCacheKey($name); return $this->handler->incrby($key, $step); } /** * 自减缓存(针对数值缓存) * * @access public * * @param string $name 缓存变量名 * @param int $step 步长 * * @return false|int */ public function dec($name, $step = 1) { $key = $this->getCacheKey($name); return $this->handler->decrby($key, $step); } /** * 删除缓存 * * @access public * * @param string $name 缓存变量名 * * @return boolean */ public function rm($name) { return $this->handler->del($this->getCacheKey($name)); } /** * 清除缓存 * * @access public * * @param string $tag 标签名 * * @return boolean */ public function clear($tag = null) { if ($tag) { // 指定标签清除 $keys = $this->getTagItem($tag); foreach ($keys as $key) { $this->handler->del($key); } $this->rm('tag_'.md5($tag)); return true; } return $this->handler->flushDB(); } /** * Returns the keys that match a certain pattern. * * @param string $pattern pattern, using '*' as a wildcard. * * @return array of STRING: The keys that match a certain pattern. * @link https://redis.io/commands/keys * @example *
     * $allKeys = $redis->keys('*');   // all keys will match this.
     * $keyWithUserPrefix = $redis->keys('user*');
     * 
*/ public function keys($pattern) { return $this->handler->keys($pattern); } /** * @param string|string[] $key1 An array of keys, or an undefined number of parameters, each a key: key1 key2 key3 * ... keyN * @param string $key2 ... * @param string $key3 ... * * @return int Number of keys deleted. * @see del() * @link https://redis.io/commands/del */ public function delete($key1, $key2 = null, $key3 = null) { return $this->handler->del($key1, $key2, $key3); } /** * 返回缓存长度 * * @param $name * * @return int */ public function lLen($name) { return $this->handler->lLen($name); } /** * Returns and removes the first element of the list. * * @param $name * * @return string */ public function lPop($name) { return $this->handler->lPop($name); } /** * Adds the string values to the head (left) of the list. Creates the list if the key didn't exist. * If the key exists and is not a list, FALSE is returned. * * @param string $key * @param string $value1 * @param null $value2 * @param null $valueN * * @return string */ public function lPush($key, $value1, $value2 = null, $valueN = null) { return $this->handler->lPush($key, $value1, $value2, $valueN); } /** * Adds the specified member with a given score to the sorted set stored at key. * * @param string $key Required key * @param float $score1 Required score * @param string $value1 Required value * @param float $score2 Optional score * @param string $value2 Optional value * @param float $scoreN Optional score * @param string $valueN Optional value * * @return int Number of values added * * @return string */ public function zAdd($key, $score1, $value1, $score2 = null, $value2 = null, $scoreN = null, $valueN = null) { return $this->handler->zAdd($key, $score1, $value1, $score2, $value2, $scoreN, $valueN); } /** * Deletes a specified member from the ordered set. * * @param string $key * @param string $member1 * @param string $member2 * @param string $memberN * * @return int Number of deleted values */ public function zRem($key, $member1, $member2 = null, $memberN = null) { return $this->handler->zRem($key, $member1, $member2, $memberN); } /** * Returns the cardinality of an ordered set. * * @param string $key * * @return int the set's cardinality */ public function zCard($key) { return $this->handler->zCard($key); } /** * Returns the cardinality of an ordered set. * * @param string $key * * @return int the set's cardinality */ public function zSize($key) { return $this->handler->zCard($key); } /** * Increments the score of a member from a sorted set by a given amount. * * @param string $key * @param float $value (double) value that will be added to the member's score * @param string $member * * @return float the new value */ public function zIncrBy($key, $value, $member) { return $this->handler->zIncrBy($key, $value, $member); } /** * Returns the number of elements of the sorted set stored at the specified key which have * scores in the range [start,end]. Adding a parenthesis before start or end excludes it * from the range. +inf and -inf are also valid limits. * * @param string $key * @param string $start * @param string $end * * @return int the size of a corresponding zRangeByScore. */ public function zCount($key, $start, $end) { return $this->handler->zCount($key, $start, $end); } /** * Returns the rank of a given member in the specified sorted set, starting at 0 for the item * with the smallest score. zRevRank starts at 0 for the item with the largest score. * * @param string $key * @param string $member * * @return int the item's score. */ public function zRank($key, $member) { return $this->handler->zRank($key, $member); } /** * Returns the score of a given member in the specified sorted set. * * @param string $key * @param string $member * * @return float */ public function zScore($key, $member) { return $this->handler->zScore($key, $member); } /** * Returns a range of elements from the ordered set stored at the specified key, * with values in the range [start, end]. start and stop are interpreted as zero-based indices: * 0 the first element, * 1 the second ... * -1 the last element, * -2 the penultimate ... * * @param string $key * @param int $start * @param int $end * @param bool $with_scores * * @return array Array containing the values in specified range. */ public function zRange($key, $start, $end, $with_scores = null) { return $this->handler->zRange($key, $start, $end, $with_scores); } /** * @param string $key * @param int $start * @param int $end * @param array $options * * @return array * @see zRangeByScore() * */ public function zRevRangeByScore($key, $start, $end, array $options = array()) { return $this->handler->zRevRangeByScore($key, $start, $end, $options); } }