Korzystanie z magicznych metod PHP sen i przebudzenie
Jaki jest użytek z metod magicznych __sleep
i __wakeup
w PHP? Przeczytałem dokumentację PHP, ale nadal nie jest jasne:
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();
Ten przykładowy kod drukuje:
Time to sleep.
Time to wakeup.
Gdybym miał zmienić nazwę __sleep
i __wakeup
na foo
i bar
wtedy robi to samo. Jakie jest właściwe wykorzystanie tych dwóch metod?
4 answers
Jak już opisano, __sleep()
jest wywoływany, gdy ty serialize()
obiekt i __wakeup()
po tobie unserialize()
to.
Serializacja jest używana do utrzymywania obiektów: otrzymasz reprezentację obiektu jako ciąg znaków, który może być następnie przechowywany w $_SESSION
, bazie danych, ciasteczkach lub gdziekolwiek indziej.
Wartości zasobów
Jednakże, serialize()
nie można serializować (tzn. przekształcić w reprezentację tekstową) wartości sof typ zasobu . Dlatego wszystkie te wartości znikną po unserialize()
ING it.
Wykres obiektu
Lub członków, a członkowie członka i.. ad infinitum
Innym, być może ważniejszym punktem jest to, że serialize()
przemierzy cały wykres obiektu $obj
, jeśli go serializujesz. Jest to świetne, gdy jest to potrzebne, ale jeśli potrzebujesz tylko części obiektu, a niektóre połączone obiekty są "specyficzne dla środowiska uruchomieniowego" i współdzielone między wieloma obiektami, ale także przez inne obiekty, możesz nie chcieć tego zachowania.
PHP poprawnie obsługuje cykliczne wykresy! Znaczenie: If (a member of) $ a links to $b, and $b links to $a jest obsługiwane poprawnie niezależnie od głębokości wielu poziomów.
Przykład-obiekty specyficzne dla sesji (współdzielone)Na przykład, obiekt $database
jest odwoływany przez $obj->db
, ale także przez inne obiekty. Będziesz chciał, aby $obj->db
były tymi samymi obiektami - po unserialize()
ing - które mają wszystkie inne obiekty w następnej sesji, a nie odizolowane instancja obiektu bazy danych.
W tym przypadku, masz __sleep()
metodę taką jak ta:
/**
/* DB instance will be replaced with the one from the current session once unserialized()
*/
public function __sleep() {
unset($this->db);
}
A następnie przywrócić go w ten sposób:
public function __wakeup() {
$this->db = <acquire this session's db object>
}
Inną możliwością jest, że obiekt jest częścią jakiejś (globalnej) struktury danych, gdzie musi być zarejestrowany. Można to oczywiście zrobić ręcznie:
$obj = unserialize($serialized_obj);
Thing::register($obj);
Jednak, jeśli jest to część Umowy obiektów, które muszą być w tym rejestrze, nie jest dobrym pomysłem, aby pozostawić to magiczne wezwanie do użytkownika obiekt. Idealnym rozwiązaniem jest, jeśli obiekt dba o swoje obowiązki, czyli jest zarejestrowany w Thing
. To właśnie __wakeup()
pozwala Ci robić to w sposób przejrzysty (tzn. nie musi już martwić się o tę magiczną zależność) z twoim klientem.
Podobnie, możesz użyć __sleep()
do" wyrejestrowania " obiektu, jeśli jest to właściwe. (Obiekty nie są niszczone podczas serializacji, ale może to mieć sens w Twoim kontekście.)
Zamknięcia
[[21]}Last but not least, closures do nie również obsługuje serializację. Oznacza to, że będziesz musiał odtworzyć wszystkie załączone zamknięcia w__wakeup()
.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-24 13:10:42
Te metody są używane podczas wywoływania serialize () i unserialize () na obiektach, aby upewnić się, że masz hook, aby usunąć niektóre właściwości, takie jak połączenia z bazą danych i ustawić je z powrotem podczas ładowania. Dzieje się tak między innymi podczas przechowywania obiektów w sesjach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-24 11:59:21
Są one podobne do funkcji hook, które możemy używać zgodnie z naszymi potrzebami. Wymyśliłem ten prosty przykład w czasie rzeczywistym. Teraz spróbuj wykonać ten kod w dwóch scenariuszach:
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));
Scenariusz 1:
Najpierw komentując metody __sleep()
i __wakeup()
, Sprawdź wyjście. Znajdziesz brakujący zasób, gdy go anulujesz.
Scenariusz 2:
Teraz spróbuj je uruchomić, przekonasz się, że obiekt wrzucony do pierwszej i ostatniej var_dump
będzie to samo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-08 06:24:24
Wypróbuj to
<?php
$ob = new sleepWakeup();
$safe_me = serialize($ob);
$ob = unserialize($safe_me);
?>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-05 20:00:56