news 2026/3/30 10:01:19

serialize() 将 PHP 变量转换为可逆的字符串表示的庖丁解牛

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
serialize() 将 PHP 变量转换为可逆的字符串表示的庖丁解牛

serialize()是 PHP 中将任意变量(除资源和闭包外)转换为可逆字符串表示的核心函数。它不仅是缓存、Session、队列等场景的基石,更是理解 PHP 内部数据结构(zval)与外部表示之间映射的关键窗口。


一、序列化格式:字符串的结构语法

serialize()输出的是人类可读但机器优先的紧凑文本格式,其语法规则如下:

<type>:<data>

常见类型编码对照表:

PHP 类型序列化前缀示例(值 → 序列化结果)
booleanbtrueb:1;
integeri42i:42;
doubled3.14d:3.14;
strings"foo"s:3:"foo";
NULLNnullN;
arraya[1,2]a:2:{i:0;i:1;i:1;i:2;}
objectOnew User("a")O:4:"User":1:{s:4:"name";s:1:"a";}

关键规则

  • 字符串长度显式声明(s:3:"foo"),支持二进制安全(含\0);
  • 数组/对象用{}包裹键值对,键值交替出现;
  • 对象包含类名、属性数量、属性名(含可见性)

二、支持的变量类型全景(PHP 8+)

类型是否支持说明
int,float,bool,string,null基础标量
array(含多维、混合键)递归序列化
object(含 private/protected 属性)保留完整状态
DateTime,stdClass等内置对象按普通对象处理
资源(resource)警告 +NULL
闭包(Closure)抛出Exception
__PHP_Incomplete_Class✅(特殊)反序列化时类未定义的占位符

💡注意
对象序列化时,仅序列化属性,不序列化方法(方法属于类,非实例状态)。


三、反序列化:unserialize()如何还原?

unserialize($str)serialize()的逆过程,其工作流如下:

步骤 1:语法解析

  • 按类型前缀(i:,s:,a:,O:)解析字符串;
  • 递归构建嵌套结构(如数组中的数组)。

步骤 2:对象重建(关键!)

  • 若遇到O:4:"User":...
    1. 检查User类是否已定义;
    2. 若已定义 → 创建新实例,直接设置属性(绕过构造函数!);
    3. 若未定义 → 创建__PHP_Incomplete_Class对象,保留原始数据。

⚠️安全风险根源
属性直接赋值 + 魔术方法(如__wakeup())自动调用 → 可能触发恶意逻辑。

步骤 3:调用__wakeup()

  • 若对象定义了__wakeup()方法,反序列化后自动调用
  • 常用于重建资源(如数据库连接)、触发事件。

四、安全边界:为什么unserialize()危险?

攻击原理(反序列化漏洞):

  1. 攻击者构造恶意序列化字符串;
  2. 应用调用unserialize($user_input)
  3. 反序列化过程中:
    • 自动调用__wakeup()/__destruct()
    • 触发对象属性中的恶意回调;
      远程代码执行(RCE)

经典案例:

// 恶意类classEvil{public$callback='system';public$command='rm -rf /';publicfunction__destruct(){($this->callback)($this->command);}}// 攻击载荷$payload='O:4:"Evil":2:{s:8:"callback";s:6:"system";s:7:"command";s:8:"whoami";}';unserialize($payload);// 执行 whoami!

防御策略:

方案说明
绝不反序列化用户输入最根本原则
使用json_encode()/json_decode()仅支持标量/数组,无对象风险
白名单类(PHP 7+)unserialize($data, ['allowed_classes' => ['User']])
禁用危险魔术方法设计对象时避免在__wakeup/__destruct中执行敏感操作

本例上下文安全
在幂等缓存中,$result = ['order_id' => 1001, ...]纯数组,无对象 →unserialize()安全


五、性能与内存特征

序列化速度(相对):

  • serialize()json_encode()(对数组);
  • serialize()>json_encode()(对对象,因 JSON 无法直接表示对象)。

内存占用:

  • 序列化字符串 ≈ 原始变量内存的 1.2~1.5 倍(含元数据);
  • 对大数组/对象,可能显著增加 Redis 内存消耗。

跨版本兼容性:

  • PHP 主版本间不保证兼容(如 PHP 7 → PHP 8 可能失败);
  • 对象属性顺序变化可能导致反序列化异常。

⚠️生产建议
若需长期存储或跨服务共享,优先用 JSON
若仅 PHP 内部临时缓存(如 Session、幂等结果),serialize()更合适


六、与 JSON 的深度对比

特性serialize()json_encode()
支持对象❌(转为stdClass或丢弃)
保留类型✅(int/bool精确还原)❌(全转为 JS 类型,如intfloat
二进制安全❌(需 base64 编码)
跨语言❌(PHP 专属)✅(通用标准)
安全性❌(反序列化危险)✅(无代码执行风险)
可读性中等

选型指南

  • 内部缓存/Sessionserialize()
  • API 通信/持久化json_encode()

七、底层:Zend 引擎如何实现?

在 PHP 源码中(ext/standard/var.c):

  • php_var_serialize()遍历 zval;
  • 根据zval.type分发到不同序列化函数(php_var_serialize_string(),php_var_serialize_array()…);
  • 对象序列化时,调用zend_hash_apply()遍历属性哈希表;
  • 输出到smart_str缓冲区(高效字符串拼接)。

🔍关键优化
长度预计算(避免多次 realloc)、引用计数处理(防止循环引用死循环)。


八、总结:serialize()的庖丁解牛要点

维度核心理解
本质PHP 变量 ↔ 字符串的双向编码协议
优势完整保留类型、结构、对象状态
风险反序列化 = 代码执行(对象场景)
适用场景内部缓存、Session、队列(可信数据)
禁忌用户输入、跨语言通信、长期存储
替代方案JSON(安全)、MessagePack(高性能)

终极口诀
“序列化保状态,反序列化藏杀机;内部用 serialize,外部用 JSON。”

作为深入理解 PHP的开发者,你应能识别:
serialize()是 PHP 运行时与外部世界交换“内存快照”的桥梁——用之得当,可提升系统效率;用之不慎,可引火烧身。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/25 9:20:42

如何快速上手Piper:游戏鼠标配置的终极指南

如何快速上手Piper&#xff1a;游戏鼠标配置的终极指南 【免费下载链接】piper GTK application to configure gaming devices 项目地址: https://gitcode.com/gh_mirrors/pip/piper Piper是一款专为Linux系统设计的开源游戏鼠标配置工具&#xff0c;它通过GTK图形界面让…

作者头像 李华
网站建设 2026/3/23 1:55:23

FaceFusion模型冷启动优化:首次加载时间缩短方案

FaceFusion模型冷启动优化&#xff1a;首次加载时间缩短方案 在视频生成平台、虚拟主播系统和AI换脸服务日益普及的今天&#xff0c;用户对“即点即出结果”的实时性要求越来越高。然而&#xff0c;许多基于深度学习的视觉应用——尤其是像 FaceFusion 这类多模型串联的人脸替换…

作者头像 李华
网站建设 2026/3/28 8:52:11

影视级人脸特效来了!FaceFusion专业平台现已开放API调用

影视级人脸特效来了&#xff01;FaceFusion专业平台现已开放API调用 在短视频日均播放量突破百亿、虚拟主播频繁登上热搜的今天&#xff0c;内容创作者对“视觉冲击力”的追求早已不止于美颜滤镜。观众不仅希望看到更真实的情感表达&#xff0c;还期待角色能在年龄、性别甚至风…

作者头像 李华
网站建设 2026/3/18 2:15:36

Python-igraph 网络分析库完整安装与使用指南

Python-igraph 网络分析库完整安装与使用指南 【免费下载链接】python-igraph Python interface for igraph 项目地址: https://gitcode.com/gh_mirrors/py/python-igraph Python-igraph 是一个功能强大的网络分析工具包&#xff0c;专为复杂网络分析和图算法设计。它结…

作者头像 李华
网站建设 2026/3/25 18:37:27

OpenCV颜色校正系统深度解析与高级应用指南

OpenCV颜色校正系统深度解析与高级应用指南 【免费下载链接】opencv_contrib 项目地址: https://gitcode.com/gh_mirrors/ope/opencv_contrib 第一部分&#xff1a;颜色偏差诊断与成因分析 色彩失真机制深度剖析 在数字图像处理中&#xff0c;颜色偏差主要源于三个核…

作者头像 李华
网站建设 2026/3/27 18:25:15

Higress如何配置智能重试策略?5个关键步骤让API调用永不中断

Higress如何配置智能重试策略&#xff1f;5个关键步骤让API调用永不中断 【免费下载链接】higress Next-generation Cloud Native Gateway | 下一代云原生网关 项目地址: https://gitcode.com/GitHub_Trending/hi/higress 还在为微服务频繁调用失败而头疼&#xff1f;每…

作者头像 李华