__serialize() 是 php 8 中用于自定义对象序列化行为的魔术方法,要求返回关联数组以明确指定需序列化的键值对,替代不安全的 __sleep()。

PHP 8 的 __serialize() 是一个用于**自定义对象序列化行为**的魔术方法,它替代了旧版中不安全、功能受限的 __sleep(),尤其在 PHP 8.0+ 中被推荐使用。
__serialize() 的作用和触发时机
当调用 serialize($obj) 时,如果类中定义了 public function __serialize(): array,PHP 就会跳过默认序列化逻辑,转而执行该方法,并**要求它返回一个关联数组**——这个数组的键是属性名,值是对应要序列化的数据。
它不负责“清理”或“关闭资源”,而是专注一件事:明确告诉 PHP “哪些数据需要被序列化,以及以什么形式”。
基本用法和签名要求
必须严格遵循以下声明(否则会报致命错误):
- 方法名必须是
__serialize - 必须是 public 访问级别
- 返回类型必须是 array(PHP 7.4+ 建议显式标注)
- 不能有参数
示例:
class User {
private string $name;
private int $age;
private ?string $token = null; // 敏感字段,不序列化
public function __construct(string $name, int $age) {
$this->name = $name;
$this->age = $age;
}
public function __serialize(): array {
// 只序列化 name 和 age,忽略 token
return [
'name' => $this->name,
'age' => $this->age,
];
}
}
$user = new User('张三', 28);
$serialized = serialize($user);
// 输出类似:O:4:"User":2:{s:4:"name";s:6:"张三";s:3:"age";i:28;}
和 __sleep() 的关键区别
-
__sleep()返回的是**属性名字符串数组**(如['name', 'age']),PHP 再按名提取值;__serialize()直接返回**键值对数组**,你完全控制数据内容和结构 -
__sleep()无法过滤私有/保护属性以外的数据(比如动态计算值、脱敏处理);__serialize()可返回任意值,甚至重命名键、转换格式、排除敏感字段 -
__serialize()不允许抛异常或调用可能失败的方法(如数据库操作),应保持轻量、确定性
配合 __unserialize() 使用
如果用了 __serialize(),反序列化时也应配对实现 __unserialize(array $data): void:
- 它接收
__serialize()返回的同一个数组 - 需手动将数据赋值给属性(包括私有/保护属性)
- 同样必须是 public,无返回值,参数类型为 array
例如:
public function __unserialize(array $data): void {
$this->name = $data['name'] ?? '';
$this->age = $data['age'] ?? 0;
}
实际注意事项
- 只读属性(PHP 8.1+)在
__unserialize()中仍可被赋值,但需注意语义一致性;若需保持只读性,应在__unserialize()中跳过赋值或抛出异常 - 避免在
__serialize()中调用外部服务、写日志或耗时操作——它应在毫秒级完成 - 若类未定义
__serialize(),PHP 会回退到默认行为(序列化所有可访问属性) - 与 JSON 序列化无关——
json_encode()不会触发它,那是JsonSerializable::jsonSerialize()的职责
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











