PHP魔术方法__sleep和__wakeup的应用(Use of PHP Magic Method

2019-06-26 12:10发布

什么是使用的__sleep__wakeup在PHP的魔术方法? 我读了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__wakeupfoobar ,然后它做同样的事情。 什么是正确使用这两种方法的?

Answer 1:

如前所述, __sleep()当你被称为serialize()对象和__wakeup()你后unserialize()它。

序列化是用来坚持的对象:你会得到一个对象作为一个字符串,它可以存储在的表示$_SESSION ,数据库,饼干或其他任何地方你的愿望。

资源值

然而, serialize() 不能序列(即转变成一个文本表示)SOF值资源类型 。 这就是为什么所有这些值会后失踪unserialize()荷兰国际集团它。

对象图

或成员,该成员的成员和......循环往复

另外,也许更重要的一点是,该serialize()会遍历整个对象图$obj ,如果你把它序列化。 这是伟大的,当你需要它,但如果你只需要对象的部分和某些链接的对象是“运行时特有的”和跨大量的对象共享,也有其他的对象,你可能不希望这种行为。

PHP处理循环图正确! 含义:如果(成员)$ A链接至$ b和$ B链接至$被处理然而正确很多层次深。

实施例 - 会话特定的(共享的)对象

例如, $database对象被引用$obj->db ,而且还通过其他对象。 您将要$obj->db是相同的对象-后unserialize()荷兰国际集团-在你的下一次会议中的所有其它对象,数据库对象的不是一个孤立的例子。

在这种情况下,你将有__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()



Answer 2:

他们很像钩子函数,我们可以根据我们的使用需求。 我想出了这个简单的实时例子。 现在尝试在两种情况下执行以下代码:

class demoSleepWakeup {
    public $resourceM;
    public $arrayM;

    public function __construct() {
        $this->resourceM = fopen("demo.txt", "w");
        $this->arrayM = array(1, 2, 3, 4); // Enter code here
    }

    public function __sleep() {
        return array('arrayM');
    }

    public function __wakeup() {
        $this->resourceM = fopen("demo.txt", "w");
    }
}

$obj = new demoSleepWakeup();
$serializedStr = serialize($obj);
var_dump($obj);
var_dump($serializedStr);
var_dump(unserialize($serializedStr));

方案1:

一是通过注释__sleep()__wakeup()方法,检查输出。 你会发现资源,当你反序列化它失踪。

方案2:

现在试着运行它取消注释它们,你会找出在第一和最后一个倾倒的对象var_dump将是相同的。



Answer 3:

呼吁对象序列化()和反序列化()时,以确保你有一个钩去掉一些属性,如数据库连接和设置他们回来时加载使用这些方法。 这发生在除其他事项外会话存储对象时。



Answer 4:

试试这个

<?php
  $ob = new sleepWakeup();
  $safe_me = serialize($ob);
  $ob = unserialize($safe_me);
?>


文章来源: Use of PHP Magic Methods __sleep and __wakeup