Использование методов PHP Magic sleep и wakeup

какая польза от __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 to foo и bar затем он делает то же самое. Как правильно использовать эти два метода?

4 ответов


как уже говорилось, __sleep() вызывается, когда вы serialize() объект и __wakeup() после unserialize() его.

сериализация используется для сохранения объектов: вы получите представление объекта в виде строки, которая затем может быть сохранена в $_SESSION, база данных, куки или где-нибудь еще вы хотите.

значения ресурсов

, serialize() не может сериализовать (т. е. преобразование в текстовое представление) значение sof тип ресурса. Вот почему все эти значения будут отсутствовать после unserialize()ing это.

объект графе

или члены, а члены члена и то ... ad infinitum

другой, возможно, более важный момент, что serialize() будет проходить весь граф объекта $obj если вы сериализовать его. Это здорово, когда вам это нужно, но если вам нужны только части объекта и некоторые связанные объекты "специфичны для среды выполнения" и совместно используются многими объектами, но и другими объектами, вы можете не хотеть такого поведения.

PHP правильно обрабатывает циклические графики! Значение: если (член) $a ссылается на $b,А $b ссылки на $a обрабатываются правильно, сколько бы уровней ни было.

пример-конкретные (общие) объекты сеанса

например, a $database "объект", на который ссылается $obj->db, но и другими объектами. Вы хотите $obj->db быть теми же объектами-после unserialize()ing-что все остальные объекты в следующем сеансе имеют, а не изолированный экземпляр объекта базы данных.

в этом случае, вы бы __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. Вот что!--5--> позволяет вам делать прозрачно (т. е. ему больше не нужно беспокоиться об этой магической зависимости) для вашего клиента.

аналогично, вы можете использовать __sleep() в "un-register" объект, если это необходимо. (Объекты не уничтожаются при сериализации, но это может иметь смысл в вашем контексте.)

закрытие

последнее, но не менее важное, закрытиене поддержка сериализации либо. Это означает, что вам придется повторно создать все прикрепленные закрытия в __wakeup().


эти методы используются при вызове serialize() и unserialize () на объектах, чтобы убедиться, что у вас есть крюк, чтобы удалить некоторые свойства, такие как подключения к базе данных, и установить их обратно при загрузке. Это происходит, в частности, при хранении объектов в сеансах.


они довольно много как функции крюка, которые мы можем использовать согласно нашим потребностям. Я придумал этот простой пример в реальном времени. Теперь попробуйте выполнить этот код в двух сценариях:

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() методы, проверьте выход. Вы найдете ресурс отсутствует, когда вы unserialize его.

вариант 2:

теперь попробуйте запустить его, раскомментировав их, вы поймете, что объект сброшен в первом и последнем var_dump было бы то же самое.


попробуйте это

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