在 PHP 内部缓存或同构系统传输场景下,serialize 序列化通常性能更高且保留类型信息;跨语言或公开接口传输必须使用 JSON 编码以确保安全与兼容性。
先说结论:优先选择 JSON 编码处理外部数据交互,仅在受信任的内部 PHP 环境且追求极致性能时使用 serialize 序列化。
- 适合:PHP 进程间缓存、同构微服务内部调用、非公开数据持久化。
- 重点看:unserialize 存在对象注入风险,严禁处理用户输入数据。
- 别忽略:JSON 编码强制 UTF-8 转换,大数据量下 CPU 开销高于 serialize。
快速处理思路
没有统一命令可直接切换编码方式,需根据业务场景修改代码逻辑。
若需自行验证性能差异,可编写本地测试脚本,使用 microtime(true) 记录编码与解码耗时,对比 memory_get_usage 内存峰值。
公开资料中没有看到可靠的量化数据表明具体性能提升百分比,因结果高度依赖 PHP 版本、数据结构复杂度及服务器硬件。
为什么会这样
serialize 是 PHP 原生格式,无需遵循通用标准,解析路径更短。
JSON 编码需要符合 RFC 标准,涉及字符集转换(如 UTF-8 校验),且 json_decode 默认生成 stdClass 对象或关联数组,类型映射成本高于 serialize 的直接类型还原。在大数据量传输下,JSON 的字符串处理开销会随数据规模线性增长,而 serialize 因保留类型元数据,字符串长度可能略长但解析速度通常更快。
分步处理
第一步:确认数据流向。若数据来自前端、第三方 API 或移动端,强制使用 json_encode 和 json_decode。
第二步:检查内部缓存场景。若仅为 Redis 或文件缓存且读写双方均为可控 PHP 代码,可评估使用 serialize 和 unserialize。
第三步:实施安全过滤。若必须使用 unserialize,确保数据源可信,或启用 allowed_classes 参数限制可实例化的类。
<?php
// 安全示例:限制允许反序列化的类
$data = unserialize($string, ["allowed_classes" => ["MyClass", "stdClass"]]);
?>第四步:压力测试。在生产环境灰度前,使用 ab 或 wrk 工具模拟高并发请求,观察 CPU 使用率变化。
怎么验证是否生效
检查应用监控日志,确认接口响应时间(RT)无明显波动。
查看服务器 CPU 使用率,JSON 编码切换为 serialize 后,同负载下 CPU 占用应略有下降。
验证数据完整性,对比编码前后的数组键值、类型是否一致,特别注意布尔值、null 和空数组在 JSON 中的表现。
常见坑
unserialize 远程代码执行风险。若攻击者可控序列化字符串,可实例化恶意类触发 __destruct 等魔术方法,参考 PHP 官方手册安全警告。
JSON 编码丢失类型信息。PHP 的索引数组在 json_encode 后可能变为 JSON 对象,解码后变回 stdClass 而非数组,需使用 JSON_FORCE_OBJECT 或手动转换。
字符集编码错误。json_encode 对非 UTF-8 字符敏感,含 GBK 等旧编码数据需先 mb_convert_encoding 转换,否则返回 null。
常见问题
serialize 和 json_encode 哪个更安全?
json_encode 更安全。serialize 配合 unserialize 存在对象注入漏洞,严禁用于不可信数据源。
大数据量下 JSON 编码会失败吗?
可能会失败。数据量超过 memory_limit 或 json_encode 深度限制时会返回 false,需检查 json_last_error。
PHP 8 对序列化性能有优化吗?
有优化但差异不明显。PHP 8 提升了 JIT 和内部函数效率,但 JSON 与 serialize 的相对性能关系基本保持一致。
参考来源
- PHP Manual, "unserialize - 安全警告", https://www.php.net/manual/zh/function.unserialize.php
- PHP Manual, "json_encode - 返回值说明", https://www.php.net/manual/zh/function.json-encode.php