// +---------------------------------------------------------------------- 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);
}
}