Utilisation des méthodes magiques de PHP sleep and wakeup
à quoi sert le __sleep
et __wakeup
méthodes magiques en PHP? J'ai lu la documentation de PHP mais elle n'est toujours pas claire:
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();
Cet exemple de code imprime:
Time to sleep.
Time to wakeup.
Si je devais renommer __sleep
et __wakeup
foo
et bar
puis il fait la même chose. Quelle est la bonne utilisation de ces deux méthodes?
4 réponses
Comme déjà décrit, __sleep()
est appelé quand vous serialize()
un objet et __wakeup()
après unserialize()
.
la sérialisation est utilisée pour persister les objets: vous obtiendrez une représentation d'un objet comme une chaîne qui peut alors être stockée dans $_SESSION
, une base de données, des cookies ou n'importe où d'autre que vous désirez.
valeurs des ressources
Cependant, serialize()
ne peut pas serialize (c'est à dire le transformer en une représentation textuelle) de la valeur des forces d'opérations spéciales de l' type de ressource. C'est pourquoi toutes ces valeurs vont disparaître après unserialize()
ing.
graphe D'objet
membres, et les membres du membre et le ... l'infini
un Autre, peut-être plus important est que serialize()
traverse tout le graphe d'objet de $obj
si vous sérialiser. C'est super quand vous en avez besoin, mais si vous avez uniquement besoin de pièces de l'objet et certains objets liés sont "spécifiques à l'exécution" et partagés entre de nombreux objets mais aussi par d'autres objets, vous ne pouvez pas vouloir ce comportement.
PHP gère correctement les graphes cycliques! Signification: si (un membre de) $a lie à $b, et $b lie à $A est manipulé correctement cependant beaucoup de niveaux profonds.
Exemple de session spécifique (partagé) des objets
Par exemple,$database
objet est référencé par $obj->db
, mais aussi par d'autres objets. Vous voulez $obj->db
pour être les mêmes objets - après unserialize()
ing - que tous les autres objets de votre prochaine session ont, pas une instance isolée de l'objet de la base de données.
Dans ce cas, vous avez __sleep()
méthode comme ceci:
/**
/* DB instance will be replaced with the one from the current session once unserialized()
*/
public function __sleep() {
unset($this->db);
}
et puis le restaurer comme ceci:
public function __wakeup() {
$this->db = <acquire this session's db object>
}
une autre possibilité est que l'objet fasse partie d'une infrastructure de données (globale) où il doit être enregistré. Vous pouvez faire cela manuellement de cours:
$obj = unserialize($serialized_obj);
Thing::register($obj);
cependant, si cela fait partie du contrat d'objets qu'il doit être dans ce registre, ce n'est pas une bonne idée de laisser cet appel magique à l'utilisateur de votre objet. La solution idéale est, si l'objet se soucie de ses responsabilités, c'est-à-dire d'être enregistré dans Thing
. C'est ce que __wakeup()
vous permet de faire de manière transparente (c'est-à-dire qu'il n'a plus besoin de s'inquiéter de cette dépendance magique) à votre client.
de Même, vous pouvez utiliser __sleep()
pour "désactiver" un objet s'il y a lieu. (Les objets ne sont pas détruits lorsqu'ils sont sérialisés, mais cela peut avoir du sens dans votre contexte.)
Fermetures
Dernier point mais non le moindre, les fermetures ne le soutien à la sérialisation. Cela signifie que vous devrez recréer toutes les fermetures attachées dans __wakeup()
.
ces méthodes sont utilisées lors de l'appel de serialize() et unserialize() sur les objets pour s'assurer que vous avez un crochet pour supprimer certaines propriétés comme les connexions de base de données et les remettre en arrière lors du chargement. Cela se produit lorsque vous stockez des objets dans des sessions, entre autres choses.
ils sont à peu près comme des fonctions de crochet, que nous pouvons utiliser selon nos besoins. J'ai trouvé un simple exemple en temps réel. Maintenant, essayez d'exécuter ce code dans deux scénarios:
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));
Scénario 1:
tout D'abord en commentant __sleep()
et __wakeup()
méthodes, vérifiez la sortie. Vous trouverez la ressource manquante lorsque vous la désérialiserez.
scénario 2:
Maintenant, essayez d'exécuter décommentant, vous allez comprendre que l'objet de dumping dans première et dernière var_dump
serait identique.
cette
<?php
$ob = new sleepWakeup();
$safe_me = serialize($ob);
$ob = unserialize($safe_me);
?>