根本原因是phpredis序列化与反序列化方式不匹配:未开启自动序列化时直接存数组会静默转空字符串,开启serializer_php后又用json_encode则导致双重编码;必须统一用json手动编解码或严格启用/禁用自动序列化。§§相关问题§§phpredis开启opt_serializer后还能否混用json_encode?如何检测redis中某个key存储的是json还是php序列化格式?thinkphp多机部署时php.ini中redis.serializer应设为什么值?$redis->set('k', [])写入后取出来是空字符串,如何修复?json_decode($redis->get('k'), true)返回null但get结果非false,可能原因是什么?

PHP 使用 phpredis 扩展存取数组时出现类型错乱(比如取出来是字符串、空值、或反序列化失败),根本原因不是 Redis 本身问题,而是序列化与反序列化方式不匹配。Redis 只存字节流,PHP 必须在写入前明确编码、读取后准确解码。
确认当前是否启用了自动序列化
phpredis 默认不自动序列化,但可通过 setOption(Redis::OPT_SERIALIZER, ...) 开启。常见错误是:开启了 PHP 原生序列化,却用 json_encode 写入,或反过来——导致读取时解码失败,返回 null 或乱码。
- 检查代码中是否调用了
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP)—— 若开启,后续所有set()都会自动serialize(),get()自动unserialize() - 若没开启自动序列化,则必须手动处理:
set('key', json_encode($arr))+json_decode(get('key'), true) -
严禁混用:例如手动
json_encode写入,又开启SERIALIZER_PHP,会导致双重编码,取出来是一串无法解析的乱码字符串
推荐统一使用 JSON 方式(最安全)
相比 PHP 原生 serialize(),JSON 更通用、可读、跨环境兼容,且不依赖类定义,避免反序列化失败风险。
- 写入:
$redis->set('user:100', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)) - 读取:
$data = json_decode($redis->get('user:100'), true);(加true确保返回数组而非对象) - 注意判空:
if ($data === null && $redis->get('user:100') !== false)表示 JSON 解析失败,可能是存储时就损坏或非 JSON 格式
避免踩坑的关键细节
类型错乱常由以下操作引发,需逐项排查:
- 直接
$redis->set('key', $array)—— phpredis 会静默转成空字符串,取出来永远是'' - 用
hSet()存整个数组 —— 该方法只接受单个 field-value,应改用hMset('key', $array) - 存了
null、资源、闭包等 JSON 不支持的类型 —— 会编码失败,返回false,但set()不报错,容易误以为成功 - 不同项目/框架混用序列化方式(如 TP5.1 用
serialize,TP8 用igbinary)—— 同一 Redis 实例里数据不可互通,必须统一策略
调试建议:快速定位错在哪一步
遇到类型错乱,别猜,用三行代码验证:
- 查原始值:
var_dump($redis->get('key'));看是不是 JSON 字符串、序列化字符串,还是空 - 试手动解码:
var_dump(json_decode($redis->get('key'), true));和var_dump(unserialize($redis->get('key')));对比结果 - 检查连接状态:
var_dump($redis->getLastError());排除网络或权限导致的静默失败
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











