请解释 PHP 类中 __sleep 和 __wakeup 魔术方法的作用及调用时机,并说明在序列化(serialize)和反序列化(unserialize)过程中它们是如何被触发的。
考察说明
考查对 PHP 魔术方法中 __sleep 和 __wakeup 的理解,以及序列化/反序列化过程中对象生命周期行为的掌握。
回答思路
- 【回答框架 1】PHP 序列化时将对象转换为可存储或传输的字符串表示。__sleep 在 serialize() 调用时被触发,它返回一个数组,指定需要被序列化的属性名;通常用于清理资源、保留最小数据,如:return [‘id’, ‘name’]。
- 【回答框架 2】__wakeup 在 unserialize() 调用时被触发,可以用于重新建立数据库连接或恢复其他资源,因为它会在对象被反序列化后自动调用。
- 【回答框架 3】两者主要用于控制序列化行为,例如排除临时数据、敏感信息或不必要的属性。注意:__sleep 返回的数组只影响属性,方法不会被序列化。
- 【回答框架 4】使用场景包括:缓存对象、Session 存储、跨网络传输等;但要注意版本差异,PHP 7.4+ 中 Serialization 接口(Serializable)已废弃,建议使用 __serialize() 和 __unserialize()。
- 【关键点 1】__sleep 在 serialize() 前调用,返回需序列化的属性列表,用于减小数据量或清理资源。
- 【关键点 2】__wakeup 在 unserialize() 后调用,适合恢复连接等资源。
- 【关键点 3】未定义或返回空数组时,序列化效果不同,需注意。
- 【易错点 1】不能直接在 __sleep 中返回未定义的属性,会导致序列化异常。
- 【易错点 2】反序列化时不会执行构造函数,只调用 __wakeup。
- 【易错点 3】不要混淆 __sleep/__wakeup 与 PHP 7.4+ 推荐的 __serialize/__unserialize。