初始化提交
This commit is contained in:
265
app/manager/sys/RedisManager.php
Normal file
265
app/manager/sys/RedisManager.php
Normal file
@@ -0,0 +1,265 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\manager\sys;
|
||||
|
||||
use think\facade\Config;
|
||||
use RedisException;
|
||||
use Redis;
|
||||
use RedisCluster;
|
||||
|
||||
class RedisManager
|
||||
{
|
||||
private static ?self $instance = null;
|
||||
private Redis|RedisCluster|null $redis = null;
|
||||
private string $prefix;
|
||||
|
||||
/**
|
||||
* 获取RedisManager实例
|
||||
*/
|
||||
public static function getInstance(?array $config = null): self
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new self($config);
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
private function __construct(?array $config = null)
|
||||
{
|
||||
$this->initializeConnection($config);
|
||||
$this->prefix = Config::get('database.connections.redis.prefix', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化Redis连接
|
||||
*/
|
||||
private function initializeConnection(?array $config = null): void
|
||||
{
|
||||
$config ??= Config::get('database.connections.redis', []);
|
||||
$hostName = config("app.host_name");
|
||||
|
||||
try {
|
||||
match($hostName) {
|
||||
'HHKK' => $this->initCluster([
|
||||
'192.168.1.3:7000',
|
||||
'192.168.1.2:7001',
|
||||
'192.168.1.31:7002'
|
||||
]),
|
||||
'H36HK' => $this->initCluster([
|
||||
'192.168.1.3:7000',
|
||||
'192.168.1.2:7001',
|
||||
'192.168.1.5:7002',
|
||||
'192.168.1.41:7003',
|
||||
'192.168.1.51:7004'
|
||||
]),
|
||||
default => $this->initSingle($config)
|
||||
};
|
||||
} catch (\Throwable $e) {
|
||||
throw new RedisException("Redis连接失败: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化单机Redis
|
||||
*/
|
||||
private function initSingle(array $config): void
|
||||
{
|
||||
$this->redis = new Redis();
|
||||
$this->redis->connect(
|
||||
$config['host'] ?? '127.0.0.1',
|
||||
$config['port'] ?? 6379,
|
||||
$config['timeout'] ?? 10
|
||||
);
|
||||
|
||||
if (!empty($config['password'])) {
|
||||
$this->redis->auth($config['password']);
|
||||
}
|
||||
|
||||
if (isset($config['db']) && is_numeric($config['db'])) {
|
||||
$this->redis->select((int)$config['db']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化Redis集群
|
||||
*/
|
||||
private function initCluster(array $nodes): void
|
||||
{
|
||||
$this->redis = new RedisCluster(null, $nodes, 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Redis实例
|
||||
*/
|
||||
public function getRedis(): Redis|RedisCluster
|
||||
{
|
||||
return $this->redis;
|
||||
}
|
||||
|
||||
/**
|
||||
* String 操作
|
||||
*/
|
||||
public function get(string $key): mixed
|
||||
{
|
||||
try {
|
||||
$value = $this->redis?->get($this->prefix . $key);
|
||||
return $this->unserialize($value);
|
||||
} catch (\Throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function set(string $key, mixed $value, int $expire = 0): bool
|
||||
{
|
||||
try {
|
||||
$value = $this->serialize($value);
|
||||
if ($expire > 0) {
|
||||
return (bool)$this->redis?->setex($this->prefix . $key, $expire, $value);
|
||||
}
|
||||
return (bool)$this->redis?->set($this->prefix . $key, $value);
|
||||
} catch (\Throwable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List 操作
|
||||
*/
|
||||
public function lPush(string $key, mixed $value): int
|
||||
{
|
||||
try {
|
||||
return $this->redis?->lPush($this->prefix . $key, $this->serialize($value)) ?? 0;
|
||||
} catch (\Throwable) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public function lRange(string $key, int $start = 0, int $end = -1): array
|
||||
{
|
||||
try {
|
||||
$data = $this->redis?->lRange($this->prefix . $key, $start, $end) ?? [];
|
||||
return array_map(fn($item) => $this->unserialize($item), $data);
|
||||
} catch (\Throwable) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash 操作
|
||||
*/
|
||||
public function hSet(string $key, string $field, mixed $value): bool
|
||||
{
|
||||
try {
|
||||
return (bool)$this->redis?->hSet(
|
||||
$this->prefix . $key,
|
||||
$field,
|
||||
$this->serialize($value)
|
||||
);
|
||||
} catch (\Throwable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function hGet(string $key, string|array|null $field = null): mixed
|
||||
{
|
||||
try {
|
||||
if ($field === null) {
|
||||
$data = $this->redis?->hGetAll($this->prefix . $key) ?? [];
|
||||
return array_map(fn($item) => $this->unserialize($item), $data);
|
||||
}
|
||||
|
||||
if (is_array($field)) {
|
||||
$data = $this->redis?->hMGet($this->prefix . $key, $field) ?? [];
|
||||
return array_map(fn($item) => $this->unserialize($item), $data);
|
||||
}
|
||||
|
||||
$value = $this->redis?->hGet($this->prefix . $key, $field);
|
||||
return $this->unserialize($value);
|
||||
} catch (\Throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set 操作
|
||||
*/
|
||||
public function sAdd(string $key, mixed $value): int
|
||||
{
|
||||
try {
|
||||
if (is_array($value)) {
|
||||
$count = 0;
|
||||
foreach ($value as $v) {
|
||||
$count += $this->redis?->sAdd(
|
||||
$this->prefix . $key,
|
||||
$this->serialize($v)
|
||||
) ?? 0;
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
return $this->redis?->sAdd($this->prefix . $key, $this->serialize($value)) ?? 0;
|
||||
} catch (\Throwable) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public function sMembers(string $key): array
|
||||
{
|
||||
try {
|
||||
$members = $this->redis?->sMembers($this->prefix . $key) ?? [];
|
||||
return array_map(fn($item) => $this->unserialize($item), $members);
|
||||
} catch (\Throwable) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用操作
|
||||
*/
|
||||
public function delete(string|array $key): bool
|
||||
{
|
||||
try {
|
||||
$keys = is_array($key)
|
||||
? array_map(fn($k) => $this->prefix . $k, $key)
|
||||
: $this->prefix . $key;
|
||||
return (bool)$this->redis?->del($keys);
|
||||
} catch (\Throwable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function exists(string $key): bool
|
||||
{
|
||||
try {
|
||||
return (bool)$this->redis?->exists($this->prefix . $key);
|
||||
} catch (\Throwable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 序列化处理
|
||||
*/
|
||||
private function serialize(mixed $data): string
|
||||
{
|
||||
if (is_array($data)) {
|
||||
return json_encode($data, JSON_UNESCAPED_UNICODE) ?: '';
|
||||
}
|
||||
return (string)$data;
|
||||
}
|
||||
|
||||
private function unserialize(mixed $data): mixed
|
||||
{
|
||||
if (!is_string($data)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$decoded = json_decode($data, true);
|
||||
return json_last_error() === JSON_ERROR_NONE ? $decoded : $data;
|
||||
}
|
||||
|
||||
private function __clone() {}
|
||||
}
|
||||
Reference in New Issue
Block a user