什么是使用的__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
和__wakeup
到foo
和bar
,然后它做同样的事情。 什么是正确使用这两种方法的?
如前所述, __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()
他们很像钩子函数,我们可以根据我们的使用需求。 我想出了这个简单的实时例子。 现在尝试在两种情况下执行以下代码:
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
将是相同的。
呼吁对象序列化()和反序列化()时,以确保你有一个钩去掉一些属性,如数据库连接和设置他们回来时加载使用这些方法。 这发生在除其他事项外会话存储对象时。
试试这个
<?php
$ob = new sleepWakeup();
$safe_me = serialize($ob);
$ob = unserialize($safe_me);
?>