当前位置:首页 > 问答 > 正文

数据处理|对象转换|php序列化和反序列化;PHP序列化与反序列化原理解析

🔍 PHP序列化与反序列化:数据变形的魔法艺术

场景引入
小明正在开发一个电商系统,需要把用户的购物车数据临时存储到文件里,他试过用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";}为例:

数据处理|对象转换|php序列化和反序列化;PHP序列化与反序列化原理解析

部分 含义
O:8:"stdClass" 对象,类名长度8,类名stdClass
:2: 对象有2个属性
属性明细(键值对)
s:4:"name" 字符串键,长度4,值为"name"

其他类型标记:

  • a - 数组
  • i - 整数
  • b - 布尔值

为什么需要序列化?

  1. 跨请求持久化:把对象存数据库/文件📁
  2. 网络传输:RPC调用时传递复杂结构🌐
  3. 深度复制:通过序列化实现对象克隆✨
// 深度复制对象
$clone = unserialize(serialize($original));

安全风险与防御 🛡️

⚠️ 危险操作

// 如果允许用户传入任意序列化数据...
unserialize($_GET['data']); // 可能执行恶意代码!

✅ 安全实践

  1. 只用json_encode()处理纯数据
  2. 必须反序列化时,校验数据来源🔐
  3. 使用__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()指定需要序列化的属性:

数据处理|对象转换|php序列化和反序列化;PHP序列化与反序列化原理解析

public function __sleep() {
    return ['username', 'email']; // 不序列化password
}

反序列化后初始化

__wakeup()恢复数据库连接等资源:

public function __wakeup() {
    $this->db = new Database();
}

JSON vs Serialize

对比项 JSON PHP序列化
数据类型支持 基础类型+数组 支持所有PHP类型
可读性 低(需解析)
安全性 较高 需严格管控
体积 较小 较大

🎯

  • 序列化是PHP独有的对象持久化方案
  • 格式类似O:长度:"类名":属性数量:{...}
  • 务必注意安全风险,避免反序列化攻击
  • 复杂场景配合__sleep()__wakeup()使用

💡 2025年新趋势:PHP 8.3+ 对序列化性能做了优化,同时推荐优先考虑更安全的替代方案如json_encode+类型转换。

下次遇到需要"冻结"对象的场景,不妨试试这个PHP特有的魔法吧!✨

数据处理|对象转换|php序列化和反序列化;PHP序列化与反序列化原理解析

发表评论