在PHP 8.1连接Redis 6.0这件事上,phpredis扩展几乎是公认的最稳妥选择——版本≥5.3.4就能完美支持ACL认证、RESP协议切换和高性能操作。需要留个心的是,尽量避免使用select()切换多库,也别用serialize()做序列化。

phpredis 扩展对 PHP 8.1 来说是连接 Redis 6.0 最省心的选项。它原生支持 Redis 6.0 的所有命令(包括 ACL、客户端缓存这些新特性),性能上更是把纯 PHP 实现的 Predis 远远甩在后面。只要扩展版本 ≥ 5.3.7(对应的就是 PHP 8.1),基本就能稳定运行,不会出什么幺蛾子。
确认 phpredis 版本是否兼容 PHP 8.1 和 Redis 6.0
PHP 8.1 要求 phpredis 至少 ≥ 5.3.4;Redis 6.0 这边,需要客户端支持 RESP2 和 RESP3 协议切换——phpredis 从 5.3.0 开始默认就用 RESP2,完全兼容。如果不兼容,典型症状是报 RedisException: Connection refused 或 RedisException: read error on connection,但明明 Redis 服务本身是正常的。这种时候多半是扩展版本太旧,或者 ABI 不匹配在作怪。
- 先跑一下
php -v,确认你实实在在用的是 PHP 8.1.x,别是早期 8.1.0 RC 版 - 再用
pecl list看看redis扩展的版本。如果没装或者版本低于 5.3.4,必须升级 - Linux 环境推荐用
pecl install redis-5.3.7显式指定版本,避免pecl install redis自动装错分支 - Windows 用户需要去 PECL 官方 Windows 构建页下载对应 TS/NTS、x64/x86 的
php_redis.dll,混用版本是行不通的
连接时必须处理 Redis 6.0 的 ACL 认证和超时参数
Redis 6.0 默认已经启用 ACL 来替代老版的 AUTH,不过 phpredis 仍然兼容旧模式。但如果你用的是 ACL 用户——比如 default 用户被禁用——那就必须显式传入用户名,否则会报 NOAUTH Authentication required。
- 传统密码认证(Redis 6.0 兼容):
$redis->auth('mypass') - ACL 用户认证(推荐):
$redis->auth('myuser', 'mypass')——注意这是两个参数,PHP 8.1 下的phpredis5.3.4+ 都支持 connect()的第三个参数是连接超时(秒),建议设为2.5;第四个参数是读写超时(可选),同样设为2.5可以防止阻塞- 别依赖
ping()来做健康检查:Redis 6.0 在连接未认证时也照样返回+PONG,正确的顺序是先auth()再ping()
setex() 和 json_encode() 组合容易踩的序列化坑
Redis 只认字符串,PHP 的数组、对象必须手动序列化。直接 set('key', $array) 会触发隐式的 __toString() 或者报出警告,结果完全不可预测;setex() 也一样。
- 正确做法:缓存前先手动
json_encode($data),取回来再json_decode($val, true) - 尽量别用
serialize():PHP 版本升级后反序列化可能失败,而且不同语言之间也不互通 - 如果值本身是数字或布尔类型,
setex()会自动转成字符串,但取回来仍然是字符串——get()永远返回 string,别指望类型能保留 - 注意
json_encode()失败时会返回false,一定要判空:if (!$json = json_encode($data)) { throw new Exception('JSON encode failed'); }
select() 切库在 Redis 6.0 中已不推荐
Redis 6.0 官方文档已经明确说了:多个数据库(SELECT 0–SELECT 15)是“遗产功能”,未来很可能会被移除。ACL 和命名空间(比如 key 前缀)才是现代的替代方案。
- 不要在代码里写
$redis->select(1);改用 key 前缀来隔离,比如cache:user:123、cache:post:456 - 如果实在要用多 DB,确保 Redis 配置中的
databases没有被设为 1(默认是 16) - 即使
phpredis的select()方法依然能用,但调用后你无法通过INFO查到当前用的是哪个 DB,调试起来相当头疼 - 生产环境建议只用 DB 0,靠 key 设计和 TTL 来控制生命周期
Redis 6.0 的 ACL 权限粒度非常细,但 phpredis 本身并不负责权限校验——它只管发命令。真正容易被忽略的是:你在代码里写的 del、flushdb 等高危命令,如果 ACL 用户没有授予对应的权限,会静默失败(返回 false 或抛 RedisException),而不是直接报权限错误。务必在测试环境用最小权限的用户跑通整个流程,否则上线后哭都来不及。