| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416 | <?php// +----------------------------------------------------------------------// | ThinkPHP [ WE CAN DO IT JUST THINK ]// +----------------------------------------------------------------------// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.// +----------------------------------------------------------------------// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )// +----------------------------------------------------------------------// | Author: liu21st <liu21st@gmail.com>// +----------------------------------------------------------------------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     * <pre>     * $allKeys = $redis->keys('*');   // all keys will match this.     * $keyWithUserPrefix = $redis->keys('user*');     * </pre>     */    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);    }}
 |