'127.0.0.1', 'port' => 6379, 'password' => '', 'select' => 0, 'timeout' => 0,// 'expire' => 0, 'persistent' => false, 'prefix' => '', ]; public function __construct(string $key) { // 判断是否有扩展(若是你的apache没reids扩展就会抛出这个异常) if (!extension_loaded('redis')) { throw new \BadFunctionCallException('not support: redis'); } $this->options = config('redis'); $func = $this->options['persistent'] ? 'pconnect' : 'connect';// 判断是否长链接 $this->Redis = new \Redis(); $redis = $this->Redis->$func($this->options['host'], $this->options['port'], $this->options['timeout']); if (!$redis) { throw new \BadFunctionCallException('connection fail: redis'); } if ($this->options['password'] != '') { $this->Redis->auth($this->options['password']); } if (0 != $this->options['select']) { $this->Redis->select($this->options['select']); } $this->Key = $this->options['prefix'] . $key; } /** * @param string $key * @param string ...$dynamic key动态值拼接 * @return RedisUtil|mixed * @throws \Exception */ public static function getInstance(string $key, string ...$dynamic) { $dynamics = ''; foreach ($dynamic as $k => $v) { if ($k == 0) { $dynamics .= $v; } else { $dynamics .= '_' . $v; } } $instanceName = uniqid(); if (!isset(self::$instances[$instanceName])) { self::$instances[$instanceName] = new self($key . $dynamics); } return self::$instances[$instanceName]; } /** * 生成唯一标识 * @param int $length 生成长度 * @return string */ public function createNo(int $length = 5): string { $redis = $this->Redis; $key = $this->Key; //指定键值新增+1 并获取 $reqNo = $redis->incr($key); //值长度已达到5位,且首位已为9,初始化 if (strlen($reqNo) >= $length && substr($reqNo, 0, 1) == 9) { $redis->set($key, 1); $reqNo = 1; } if ($reqNo == 1) { //设置月末到期 $expire = strtotime(date('Y-m', strtotime("+1 month")) . '-01 00:00:00') - time(); $redis->expire($key, $expire); } return sprintf("%0{$length}d", $reqNo); } /** * 限制尝试次数 (设定时间内) * @param int $second 秒 * @param int $Times 次数 * @return false|int */ public function tryTimes(int $second, int $Times = 5) { $redis = $this->Redis; $key = $this->Key; //指定键值新增+1 并获取 $count = $redis->incr($key); if ($count > $Times) { return false; } //设置过期时间 if ($count == 1) { $redis->expire($key, $second); } return (int)$count; } /** * 加锁 * @param int $timeout 锁的过期时间 * @return false|string */ public function Lock(int $timeout = 10) { $redis = $this->Redis; $lockName = $this->Key;//锁的名字 #获取唯一标识符 $identifier = uniqid(); #锁的过期时间 $end = time() + $timeout; #循环获取锁 while (time() < $end) { #查看$lockName是否被上锁,为$lockName设置过期时间,防止死锁 if ($redis->set($lockName, $identifier, ['ex' => $timeout, 'nx'])) { return $identifier; } #停止0.001ms usleep(0.001); } return false; } /** * 释放锁 * @param string $identifier 锁的唯一值 * @return bool */ public function releaseLock(string $identifier): bool { $redis = $this->Redis; $lockName = $this->Key;//锁的名字 // 判断是锁有没有被其他客户端修改 if ($redis->get($lockName) != $identifier) { #其他客户端修改了锁,不能删除别人的锁 return false; } #释放锁 $redis->del($lockName); return true; } public function setex($value, int $second) { $redis = $this->Redis; $key = $this->Key; return $redis->setex($key, $second, $value); } public function set($value, $options = null) { $redis = $this->Redis; $key = $this->Key; return $redis->set($key, $value, $options); } public function get() { $redis = $this->Redis; $key = $this->Key; return $redis->get($key); } public function del() { $redis = $this->Redis; $key = $this->Key; return $redis->del($key); } //加入list public function lPush($value) { $redis = $this->Redis; $key = $this->Key; return $redis->lPush($key, $value); } //删除右边 public function rPop() { $redis = $this->Redis; $key = $this->Key; return $redis->rPop($key); } public function rPush($value) { $redis = $this->Redis; $key = $this->Key; return $redis->rPush($key, $value); } public function lPopLine($num) { $redis = $this->Redis; $key = $this->Key; $pipe = $redis->multi(\Redis::PIPELINE); $pipe->lRange($key, 0, $num - 1); $pipe->lTrim($key, $num, -1); return $pipe->exec(); } //list长度 public function lLen() { $redis = $this->Redis; $key = $this->Key; return $redis->llen($key); } public function zadd($score, $member) { $redis = $this->Redis; $key = $this->Key; return $redis->zadd($key, $score, $member); } public function zcard() { $redis = $this->Redis; $key = $this->Key; return $redis->zcard($key); } public function zrem($member) { $redis = $this->Redis; $key = $this->Key; return $redis->zrem($key, $member); } // 递增返回 public function zRange($start_score = 0, $end_score = -1, $options = null) { $redis = $this->Redis; $key = $this->Key; return $redis->zrange($key, $start_score, $end_score,$options); } // 递减返回 public function zRevRange($start_score = 0, $end_score = -1, $options = null) { $redis = $this->Redis; $key = $this->Key; return $redis->zRevRange($key, $start_score, $end_score,$options); } public function zRevRank($start, $end, $scores = null) { $redis = $this->Redis; $key = $this->Key; return $redis->zRevRange($key, $start, $end,$scores); } public function zRank($member) { $redis = $this->Redis; $key = $this->Key; return $redis->zRank($key, $member); } public function zUnionStore($output, $zSetKeys, ?array $weights = null, $aggregateFunction = null) { $redis = $this->Redis; return $redis->zUnionStore($output, $zSetKeys, $weights, $aggregateFunction); } public function hSet($field, $value) { $redis = $this->Redis; $key = $this->Key; return $redis->hset($key, $field, $value); } public function hKeys() { $redis = $this->Redis; $key = $this->Key; return $redis->hkeys($key); } public function hGet($field) { $redis = $this->Redis; $key = $this->Key; return $redis->hget($key, $field); } public function hDel($field) { $redis = $this->Redis; $key = $this->Key; return $redis->hdel($key, $field); } public function hGetAll() { $redis = $this->Redis; $key = $this->Key; return $redis->hGetAll($key); } }