使用PHP Magic方法__sleep和__wakeup [英] Use of PHP Magic Methods __sleep and __wakeup

查看:74
本文介绍了使用PHP Magic方法__sleep和__wakeup的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What is the use of the __sleep and __wakeup magic methods in PHP? I read the PHP documentation but it's still not clear:

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,则它执行相同的操作.这两种方法的正确用法是什么?

If I were to rename __sleep and __wakeup to foo and bar then it does the same thing. What is the proper use of these two methods?

推荐答案

如上所述, __sleep() > 对象和 __wakeup() unserialize() 之后.

As already described, __sleep() is called when you serialize() an object and __wakeup() after you unserialize() it.

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

Serialization is used to persist objects: You will get a representation of an object as a string that can then be stored in $_SESSION, a database, cookies or anywhere else you desire.

但是,serialize() 不能

However, serialize() cannot serialize (i.e. transform into a textual representation) value sof the resource type. This is why all of these values will go missing after unserialize()ing it.

或成员,以及成员的成员和... ad infinitum

or members, and the member's members and the ... ad infinitum

也许是更重要的一点是,如果对serialize()进行序列化,它将遍历$obj的整个对象图.当您需要它时,这是很好的选择,但是如果您只需要对象的一部分,并且某些链接的对象是运行时特定的",并且可以在许多对象之间共享,也可以由其他对象共享,那么您可能就不需要这种行为.

Another, perhaps more important point is, that serialize() will traverse the entire object graph of $obj if you serialize it. This is great when you need it, but if you only need parts of the object and certain linked objects are "runtime-specific" and shared across a lot of objects but also by other objects, you may not want that behavior.

PHP可以正确处理循环图!含义:如果$ a(的一个成员)链接到$ b,而$ b链接到$ a,则无论处理了多少层,都可以正确处理.

PHP handles cyclic graphs correctly! Meaning: If (a member of) $a links to $b, and $b links to $a is handled correctly however many levels deep.

例如,$obj->db对象被$obj->db引用,但其他对象也被引用.在unserialize()添加之后,您将希望$obj->db是下一个会话中所有其他对象都具有的相同对象,而不是数据库对象的隔离实例.

For instance, a $database object is referenced by $obj->db, but also by other objects. You will want $obj->db to be the same objects - after unserialize()ing - that all the other objects in your next session have, not an isolated instance of the database object.

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

In this case, you would have __sleep() method such as this:

/**
/* 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>
}

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

Another possibility is, that the object is part of some (global) datastructure where it needs to be registered. You could do this manually of course:

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

但是,如果它是对象契约的一部分,则它需要在该注册表中,所以将这个神奇的调用留给对象的用户不是一个好主意.理想的解决方案是,如果对象关心其职责,即在Thing中注册.这就是__wakeup()允许您透明地对客户端执行的操作(即,他不再需要担心这种神奇的依赖关系).

However, if it is part of the objects contract that it needs to be in that registry, it's not a good idea to leave this magical call up to the user of your object. The ideal solution is, if the object cares about it's responsibilities, i.e. being registered in Thing. That's what __wakeup() allows you to do transparently (i.e. he need no longer worry about that magical dependency) to your client.

类似地,如果适当的话,您可以使用__sleep()来取消注册"对象. (对象在序列化时不会被销毁,但是在您的上下文中可能是有意义的.)

Similarly, you could use __sleep() to "un-register" an object if appropriate. (Objects are not destroyed when they're serialized, but it may make sense in your context.)

最后但并非最不重要的一点,闭包也不支持序列化.这意味着您将不得不在__wakeup()中重新创建所有附加的闭包.

Last but not least, closures do not support serialization either. This means that you will have to re-create all attached closures in __wakeup().

这篇关于使用PHP Magic方法__sleep和__wakeup的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆