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() {} }