508 lines
16 KiB
PHP
508 lines
16 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace App\Cache\Redis;
|
||
|
||
use Hyperf\Context\ApplicationContext;
|
||
use Hyperf\Redis\RedisFactory;
|
||
use Hyperf\Redis\RedisProxy;
|
||
use Psr\Container\ContainerExceptionInterface;
|
||
use Psr\Container\NotFoundExceptionInterface;
|
||
use Redis;
|
||
use RedisException;
|
||
|
||
class RedisCache
|
||
{
|
||
/**
|
||
* 获取 redis 对象
|
||
* @param string $poolName
|
||
* @return RedisProxy
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
*/
|
||
private function getRedis(string $poolName = 'default'): RedisProxy
|
||
{
|
||
return ApplicationContext::getContainer()->get(RedisFactory::class)->get($poolName);
|
||
}
|
||
|
||
|
||
// +--------------------------------------------------------------------------------------------------------------------------------------------
|
||
// | atom 原子操作
|
||
// +--------------------------------------------------------------------------------------------------------------------------------------------
|
||
/**
|
||
* @param string $script
|
||
* @param array $array
|
||
* @param int $num
|
||
* @param string $poolName
|
||
* @return mixed
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function eval(string $script, array $array, int $num = 1, string $poolName = 'default'): mixed
|
||
{
|
||
return $this->getRedis($poolName)->eval($script, $array, $num);
|
||
}
|
||
|
||
|
||
/**
|
||
* @param string $key
|
||
* @param int $ttl
|
||
* @param string $poolName
|
||
* @return int
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function addLock(string $key, int $ttl = 5, string $poolName = 'lock'): int
|
||
{
|
||
$script = <<<lua
|
||
local isLock = redis.call('exists',KEYS[1])
|
||
if isLock == 1 then
|
||
return 0
|
||
else
|
||
redis.call('set',KEYS[1],1)
|
||
redis.call('Expire',KEYS[1],ARGV[1])
|
||
return 1;
|
||
end
|
||
lua;
|
||
|
||
return $this->getRedis($poolName)->eval($script, [$key, $ttl], 1);
|
||
}
|
||
|
||
/**
|
||
* @param string $key
|
||
* @param string $poolName
|
||
* @return int|bool
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface|RedisException
|
||
*/
|
||
public function delLock(string $key, string $poolName = 'lock'): int|bool
|
||
{
|
||
return $this->delete($key, $poolName);
|
||
}
|
||
|
||
|
||
// +--------------------------------------------------------------------------------------------------------------------------------------------
|
||
// | key
|
||
// +--------------------------------------------------------------------------------------------------------------------------------------------
|
||
/**
|
||
* 判断 key 是否存在
|
||
* @param string $key
|
||
* @param string $poolName
|
||
* @return int|bool
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function exists(string $key, string $poolName = 'default'): int|bool
|
||
{
|
||
return $this->getRedis($poolName)->exists($key);
|
||
}
|
||
|
||
/**
|
||
* 删除
|
||
* @param string $key
|
||
* @param string $poolName
|
||
* @return int|bool
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function delete(string $key, string $poolName = 'default'): int|bool
|
||
{
|
||
return $this->getRedis($poolName)->del($key);
|
||
}
|
||
|
||
/**
|
||
* @param string $key
|
||
* @param int $ex
|
||
* @param string $poolName
|
||
* @return bool
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function expire(string $key, int $ex, string $poolName = 'default'): bool
|
||
{
|
||
return $this->getRedis($poolName)->expire($key, $ex);
|
||
}
|
||
|
||
/**
|
||
* 返回过期时间 -1=key存在未设置过期时间 -2=key不存在 >0 = 过期时间(秒)
|
||
* @param string $key
|
||
* @param string $poolName
|
||
* @return bool|int|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function ttl(string $key, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->ttl($key);
|
||
}
|
||
|
||
|
||
// +--------------------------------------------------------------------------------------------------------------------------------------------
|
||
// | string
|
||
// +--------------------------------------------------------------------------------------------------------------------------------------------
|
||
/**
|
||
* 设置一个key
|
||
* @param string $key
|
||
* @param string $value
|
||
* @param string $poolName
|
||
* @return bool
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function set(string $key, string $value, string $poolName = 'default'): bool
|
||
{
|
||
return $this->getRedis($poolName)->set($key, $value);
|
||
}
|
||
|
||
/**
|
||
* 获取key
|
||
* @param string $key
|
||
* @param string $poolName
|
||
* @return false|mixed|Redis|string
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function get(string $key, string $poolName = 'default'): mixed
|
||
{
|
||
return $this->getRedis($poolName)->get($key);
|
||
}
|
||
|
||
/**
|
||
* 添加一个有过期值的key (ps:如果 key 已经存在, setEx 命令将会替换旧的值。)
|
||
* @param string $key
|
||
* @param string $value
|
||
* @param int $ttl
|
||
* @param string $poolName
|
||
* @return Redis|bool
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function setEx(string $key, string $value, int $ttl, string $poolName = 'default'): Redis|bool
|
||
{
|
||
return $this->getRedis($poolName)->setex($key, $ttl, $value);
|
||
|
||
}
|
||
|
||
|
||
/**
|
||
* 将 key 中储存的数字值增一。
|
||
* 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
|
||
* @param $key
|
||
* @param string $poolName
|
||
* @return false|int|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function incr($key, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->incr($key);
|
||
}
|
||
|
||
// +--------------------------------------------------------------------------------------------------------------------------------------------
|
||
// | set
|
||
// +--------------------------------------------------------------------------------------------------------------------------------------------
|
||
/**
|
||
* 判断 value 元素是否是集合 key 的成员
|
||
* 如果 member 元素是集合的成员,返回 1 。
|
||
* 如果 member 元素不是集合的成员,或 key 不存在,返回 0 。
|
||
* @param $key
|
||
* @param $value
|
||
* @param string $poolName
|
||
* @return bool|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function sIsMember($key, $value, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->sIsMember($key, $value);
|
||
}
|
||
|
||
|
||
/**
|
||
* 添加集合成员
|
||
* @param $key
|
||
* @param $value
|
||
* @param string $poolName
|
||
* @return bool|int|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
*/
|
||
public function sAdd($key, $value, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->sAdd($key, $value);
|
||
}
|
||
|
||
/**
|
||
* 获取集合所有内容
|
||
* @param $key
|
||
* @param string $poolName
|
||
* @return array|false|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function sMembers($key, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->sMembers($key);
|
||
}
|
||
|
||
/**
|
||
* 删除集合成员
|
||
* @param $key
|
||
* @param $value
|
||
* @param string $poolName
|
||
* @return false|int|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
*/
|
||
public function sRem($key, $value, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->sRem($key, $value);
|
||
}
|
||
|
||
/**
|
||
* 集合批量添加
|
||
* @param $key
|
||
* @param array $values
|
||
* @param string $poolName
|
||
* @return bool|int|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function sAddBatch($key, array $values, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->sAddArray($key, $values);
|
||
}
|
||
|
||
// +--------------------------------------------------------------------------------------------------------------------------------------------
|
||
// | hash
|
||
// +--------------------------------------------------------------------------------------------------------------------------------------------
|
||
/**
|
||
* 设置多个key-value 的 hash值
|
||
* @param $key
|
||
* @param $hashKeys
|
||
* @param null $expire
|
||
* @param string $poolName
|
||
* @return bool|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function hMset($key, $hashKeys, $expire = null, string $poolName = 'default')
|
||
{
|
||
$result = $this->getRedis($poolName)->hMset($key, $hashKeys);
|
||
if ($expire) {
|
||
$this->getRedis($poolName)->expire($key, $expire);
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 返回列表 key 的集合数据
|
||
* @param $key
|
||
* @param string $poolName
|
||
* @return false|array|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function hGetAll($key, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->hGetAll($key);
|
||
}
|
||
|
||
/**
|
||
* 设置单个key-value 的 hash值
|
||
* @param $key
|
||
* @param $hashKey
|
||
* @param $hashValue
|
||
* @param int $expire
|
||
* @param string $poolName
|
||
* @return bool|int|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function hSet($key, $hashKey, $hashValue, int $expire = 0, string $poolName = 'default')
|
||
{
|
||
$result = $this->getRedis($poolName)->hSet($key, $hashKey, $hashValue);
|
||
if ($expire) {
|
||
$this->getRedis($poolName)->expire($key, $expire);
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 获取单个字段的 hash 值
|
||
* @param $key
|
||
* @param $hashKey
|
||
* @param string $poolName
|
||
* @return false|mixed|Redis|string
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function hGet($key, $hashKey, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->hGet($key, $hashKey);
|
||
}
|
||
|
||
/**
|
||
* 删除hash某个值
|
||
* @param $key
|
||
* @param $hashKey
|
||
* @param string $poolName
|
||
* @return bool|int|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function hDel($key, $hashKey, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->hDel($key, $hashKey);
|
||
}
|
||
|
||
/**
|
||
* 查找hash某个值
|
||
* @param $key
|
||
* @param $hashKey
|
||
* @param string $poolName
|
||
* @return bool|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function hExists($key, $hashKey, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->hExists($key, $hashKey);
|
||
}
|
||
|
||
|
||
/**
|
||
* 单个字段的 hash 值原子增加
|
||
* @param $key
|
||
* @param $hashKey
|
||
* @param $hashValue
|
||
* @param string $poolName
|
||
* @return false|int|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function HIncrBy($key, $hashKey, $hashValue, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->hincrby($key, $hashKey, $hashValue);
|
||
}
|
||
|
||
|
||
// +--------------------------------------------------------------------------------------------------------------------------------------------
|
||
// | list
|
||
// +--------------------------------------------------------------------------------------------------------------------------------------------
|
||
/**
|
||
* 从左边入
|
||
* @param string $key
|
||
* @param string $data
|
||
* @param string $poolName
|
||
* @return false|int|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function lPush(string $key, string $data, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->lPush($key, $data);
|
||
}
|
||
|
||
/**
|
||
* 从右边出
|
||
* @param $key
|
||
* @param string $poolName
|
||
* @return array|bool|mixed|Redis|string
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function rPop($key, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->rPop($key);
|
||
}
|
||
|
||
/**
|
||
* 批量加入数据
|
||
* @param $data
|
||
* @param string $poolName
|
||
* @return RedisProxy
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
*/
|
||
public function lPushBatch($data, string $poolName = 'default')
|
||
{
|
||
$result = $this->getRedis($poolName);
|
||
call_user_func_array([$result, 'lPush'], $data);
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 返回列表 key 的长度
|
||
* @param $key
|
||
* @param string $poolName
|
||
* @return bool|int|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function lLen($key, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->lLen($key);
|
||
}
|
||
|
||
// +--------------------------------------------------------------------------------------------------------------------------------------------
|
||
// | sorted set
|
||
// +--------------------------------------------------------------------------------------------------------------------------------------------
|
||
/**
|
||
* 返回有序集 key 中,成员 member 的 score 值。
|
||
* 如果 member 元素不是有序集 key 的成员,或 key 不存在,返回 nil 。
|
||
* @param $key
|
||
* @param $value
|
||
* @param string $poolName
|
||
* @return bool|float|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function zScore($key, $value, string $poolName = 'default')
|
||
{
|
||
return $this->getRedis($poolName)->zScore($key, $value);
|
||
}
|
||
|
||
/**
|
||
* 加入有序集合
|
||
* @param $key
|
||
* @param $score
|
||
* @param string $poolName
|
||
* @param ...$value
|
||
* @return false|int|Redis
|
||
* @throws ContainerExceptionInterface
|
||
* @throws NotFoundExceptionInterface
|
||
* @throws RedisException
|
||
*/
|
||
public function zAdd($key, $score, string $poolName = 'default', ...$value)
|
||
{
|
||
return $this->getRedis($poolName)->zAdd($key, $score, ...$value);
|
||
}
|
||
|
||
|
||
} |