上一篇
场景引入:
小明正在开发一个电商系统,需要把用户的购物车数据临时存储到文件里,他试过用json_encode
,但遇到对象时就头疼了——怎么把整个对象"暂停"保存,下次又能"复活"继续用呢?🤔 这时,PHP的序列化(Serialization)和反序列化(Unserialization)闪亮登场!
简单说,序列化就是把PHP变量(包括对象)转换成可存储/传输的字符串的过程,就像把乐高玩具拆解成零件清单📋,反序列化则是逆向操作——根据清单重新拼回乐高。
$user = new stdClass(); $user->name = "小明"; $user->level = "VIP"; // 序列化 $serialized = serialize($user); // 输出:O:8:"stdClass":2:{s:4:"name";s:6:"小明";s:5:"level";s:3:"VIP";} // 反序列化 $restoredUser = unserialize($serialized); echo $restoredUser->name; // 输出:小明
以O:8:"stdClass":2:{s:4:"name";s:6:"小明";s:5:"level";s:3:"VIP";}
为例:
部分 | 含义 |
---|---|
O:8:"stdClass" |
对象,类名长度8,类名stdClass |
:2: |
对象有2个属性 |
属性明细(键值对) | |
s:4:"name" |
字符串键,长度4,值为"name" |
其他类型标记:
a
- 数组 i
- 整数 b
- 布尔值 // 深度复制对象 $clone = unserialize(serialize($original));
// 如果允许用户传入任意序列化数据... unserialize($_GET['data']); // 可能执行恶意代码!
json_encode()
处理纯数据 __wakeup()
方法做对象初始化检查 class SafeClass { public function __wakeup() { if (!valid_source()) { throw new Exception("非法数据!"); } } }
序列化会保留私有属性,但类名和属性名会特殊编码:
class User { private $password = "123456"; } // 序列化后:O:4:"User":1:{s:14:"%00User%00password";s:6:"123456";}
实现__sleep()
指定需要序列化的属性:
public function __sleep() { return ['username', 'email']; // 不序列化password }
用__wakeup()
恢复数据库连接等资源:
public function __wakeup() { $this->db = new Database(); }
对比项 | JSON | PHP序列化 |
---|---|---|
数据类型支持 | 基础类型+数组 | 支持所有PHP类型 |
可读性 | 高 | 低(需解析) |
安全性 | 较高 | 需严格管控 |
体积 | 较小 | 较大 |
O:长度:"类名":属性数量:{...}
__sleep()
和__wakeup()
使用 💡 2025年新趋势:PHP 8.3+ 对序列化性能做了优化,同时推荐优先考虑更安全的替代方案如
json_encode
+类型转换。
下次遇到需要"冻结"对象的场景,不妨试试这个PHP特有的魔法吧!✨
本文由 王布欣 于2025-07-31发表在【云服务器提供商】,文中图片由(王布欣)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/492340.html
发表评论