PHP 8.1: Serializable 接口弃用
PHP 支持 serialize
和 unserialize
函数用于将类对象、数组及其他标量数据转换为序列化字符串格式,及从序列化字符串中重建。
PHP 类可以提供他们自己的序列化实现。比如,类可以排除特定敏感信息,不将其添加到序列化字符串中,或者类可以从序列化文本中获取的服务器 URL 重新建立与远程服务器的连接。
PHP 类有三种方式提供自定义序列化逻辑:
__sleep
和__wakeup
魔术方法Serializable
接口及Serializable::serialize
和Serializable::unserialize
方法 (自 PHP 5.1 起)__serialize
和__unserialize
魔术方法 (自 PHP 7.4 起)
实现 __serialize
和 __unserialize
方法是推荐的方式,因为它避免了 __sleep
/_wakeup
方法和 Serializable
接口的一些陷阱。
在 PHP 8.1, 实现 Serializable
接口而不实现 __serialize
和 __unserialize
方法将被弃用。
class Test implements Serializable{
public function serialize() {}
public function unserialize($data) {}
}
Deprecated: Test implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in ... on line ...
JsonSerializable
接口不受影响。- 从 PHP 8.0 起,类魔术方法签名严格执行。
早在2019年,就有人提议添加两个新的魔术方法 __serialize
和 __unserialize
,因为 __wakeup
+ __sleep
和 Serializable
接口方法由于实现复杂性及其错误行为而不理想。
PHP 8.1中的这种弃用是这一变化的延续,即在没有新的魔术方法的情况下弃用实现 Serializable
接口,并最终在PHP 9.0中删除 Serializable
接口。
如果一个类同时实现 Serializable
接口方法和魔术方法,则魔术方法优先,并且不会发出弃用通知。
在 PHP 7.4 及更高版本中,__serialize
和 __unserialize
方法是在 serialize()
/userialize
调用期间执行的,而不是 Serializable
接口中的 serialize
/unserialized
方法。PHP 8.1中也不会有任何弃用通知。
class Test implements Serializable{
public function __serialize(): array {}
public function __unserialize(array $data): void {}
public function serialize(): array {}
public function unserialize(string $data): void {}
}
相关变更
- PHP 8.1:
PDO::FETCH_SERIALIZE
弃用
向后兼容性影响
请注意,如果类还实现了 __serialize
和 __unserialize
方法,则不会发出弃用通知。
如果一个类同时实现 Serializable
接口方法和魔术方法,则魔术方法优先。
在使用 PHP 7.4 作为最低版本的应用程序上,可以安全地放弃 Serializable
接口实现,并实现新的 __serialize
和 __unserialize
方法。
在必须支持早于 PHP 7.4 的 PHP 版本的应用程序上,需同时实现 Serializable
接口(将在 PHP<=7.3 上使用)和 __serialize
/ __unserialize
方法(适用于 PHP 7.4、8.0及更高版本)。