gpt4 book ai didi

php - PHP 魔术方法 __sleep 和 __wakeup 的使用

转载 作者:IT王子 更新时间:2023-10-29 01:04:07 26 4
gpt4 key购买 nike

PHP 中的__sleep__wakeup 魔术方法有什么用?我阅读了 PHP 文档,但仍然不清楚:

class sleepWakeup {

public function __construct() {
// constructor //
}

public function __sleep() {
echo 'Time to sleep.';
}

public function __wakeup() {
echo 'Time to wakeup.';
}

}

$ob = new sleepWakeup();

// call __sleep method
echo $ob->__sleep();

echo "\n";

// call __wakeup method
echo $ob->__wakeup();

此示例代码打印:

Time to sleep.
Time to wakeup.

如果我将 __sleep__wakeup 重命名为 foobar 那么它会做同样的事情。这两种方法的正确使用方法是什么?

最佳答案

如前所述,__sleep()当您 serialize() 时调用一个对象和__wakeup()在你之后unserialize()它。

序列化用于持久化对象:您将获得对象的表示形式为字符串,然后可以将其存储在 $_SESSION、数据库、cookie 或您想要的任何其他地方。

资源值(value)

但是,serialize() 不能序列化(即转换为文本表示形式)resource type 的值.这就是为什么在 unserialize() 之后所有这些值都会丢失的原因。

对象图

或成员,以及成员的成员和……无限

另外,也许更重要的一点是,如果你序列化 serialize() 将遍历 $obj 的整个对象图。这在您需要时非常有用,但如果您只需要对象的一部分,并且某些链接对象是“特定于运行时的”并且在许多对象之间共享并且还由其他对象共享,那么您可能不希望这种行为。

PHP 正确处理循环图!含义:如果 $a 的(成员)链接到 $b,并且 $b 链接到 $a 的处理正确,但无论层级有多深。

示例 - session 特定(共享)对象

例如,$database 对象被 $obj->db 引用,但也被其他对象引用。您将希望 $obj->db 成为相同的对象 - 在 unserialize()ing 之后 - 下一个 session 中的所有其他对象都具有,而不是数据库对象。

在这种情况下,您将有 __sleep() 方法,例如:

/**
/* DB instance will be replaced with the one from the current session once unserialized()
*/
public function __sleep() {
unset($this->db);
}

然后像这样恢复它:

public function __wakeup() {
$this->db = <acquire this session's db object>
}

另一种可能性是,对象是需要注册的某些(全局)数据结构的一部分。您当然可以手动执行此操作:

$obj = unserialize($serialized_obj);
Thing::register($obj);

但是,如果它是需要在该注册表中的对象契约的一部分,那么将这个神奇的调用留给对象的用户并不是一个好主意。理想的解决方案是,如果对象关心它的职责,即在 Thing 中注册。这就是 __wakeup() 允许您对您的客户透明地做的事情(即他不再需要担心这种神奇的依赖)。

同样,如果合适,您可以使用 __sleep() 来“取消注册”对象。 (对象在序列化时不会被销毁,但在您的上下文中可能有意义。)

关闭

最后但同样重要的是,闭包也支持序列化。这意味着您必须在 __wakeup() 中重新创建所有附加的闭包。

关于php - PHP 魔术方法 __sleep 和 __wakeup 的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11630341/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com