Использование методов 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);
?>