PHP中的对象序列化:函数、方法及实践示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

PHP中的对象序列化:完整指南



序列化是将复杂的数据结构(对象、数组)转换为字符串或二进制格式的过程,以便可以将其保存到文件、通过网络传输或缓存。在PHP中,这一机制通过内置函数serialize()和unserialize()实现。在本文中,我们将详细解析对象序列化的工作原理、存在的陷阱以及如何使用魔术方法对过程进行精细控制。



序列化的基本函数



PHP提供了两个用于处理序列化的关键函数:



  • serialize($value) — 将值(resource类型除外)转换为适合存储的字符串。对于对象,会保存类名和所有属性(包括私有和受保护的属性)。
  • unserialize($string) — 从字符串中恢复原始值。对于对象,会自动调用类的构造函数(如果已定义)并填入保存的属性。


对象序列化的简单示例



考虑一个基础类User及其序列化:



<?phpclass User {    public $name;    public $email;    private $password;

public function __construct($name, $email, $password) { $this->name = $name; $this->email = $email; $this->password = $password; }}

$user = new User('伊万', 'ivan@example.com', 'secret123');$serialized = serialize($user);echo $serialized;// 输出:O:4:"User":3:{s:4:"name";s:8:"伊万";s:5:"email";s:16:"ivan@example.com";s:12:"\\0User\\0password";s:9:"secret123";}?>


请注意:私有属性$password在字符串中显示为\\0User\\0password——这是私有字段的特殊表示法,其中\\0是空字节。



从序列化字符串恢复对象



<?php$serialized = 'O:4:"User":3:{s:4:"name";s:8:"伊万";s:5:"email";s:16:"ivan@example.com";s:12:"\\0User\\0password";s:9:"secret123";}';$user = unserialize($serialized);echo $user->name; // 伊万echo $user->email; // ivan@example.com// 私有属性password也已恢复,但无法直接访问?>


重要提示: 反序列化时,如果类尚未定义,PHP会尝试加载该类。如果类不存在,则会创建一个内置类__PHP_Incomplete_Class的实例。



魔术方法 __sleep() 和 __wakeup()



为了控制序列化过程,PHP提供了两个魔术方法:



  • __sleep() — 在序列化之前调用。应返回一个需要序列化的属性名称数组。适用于关闭数据库连接、释放资源或隐藏敏感数据。
  • __wakeup() — 在反序列化之后立即调用。用于重新连接数据库、恢复资源或检查数据完整性。


__sleep() 和 __wakeup() 示例



<?phpclass DatabaseConnection {    private $host;    private $user;    private $password;    private $connection;

public function __construct($host, $user, $password) { $this->host = $host; $this->user = $user; $this->password = $password; $this->connect(); }

private function connect() { // 模拟连接 $this->connection = "连接到 {$this->host} 的资源"; }

public function __sleep() { // 不序列化连接资源,只序列化用于重新连接的数据 return ['host', 'user', 'password']; }

public function __wakeup() { // 恢复连

推荐