En el ultimo artículo de la serie empecé a hablar sobre los métodos mágicos construct y destruct, y para seguir con el tema de los métodos mágicos quiero hablar hoy de los métodos sleep y wakeup.

¿Os acordáis de Super Mario? Usaré su clase a modo de ejemplo pero quitando métodos y atributos para no contribuir a crear confusión. Pensad por un momento que tenéis que guardar el Objeto Mario en la base de datos de vuestra aplicación, para ello tenemos que convertirlo en un string, por suerte php provee de dos funciones para esto: serialize y unserialize.

Voy a explicar brevemente estas dos simples funciones apoyándome con var_dump:

string(19) "Esto es un atributo" } //Serializamos la clase $claseSerializada = serialize($clase); var_dump($claseSerializada); //Imprime: string(59) "O:7:"MiClase":1:{s:7:"mensaje";s:19:"Esto es un atributo";}" //Deserializamos la clase $claseRecuperada = unserialize($claseSerializada); var_dump($claseRecuperada); //Imprime: object(MiClase)#2 (1) { ["mensaje"]=> string(19) "Esto es un atributo" } ?>

Como podemos ver al crear el objeto vardump nos dice que el parámetro pasado es del tipo “*object(MiClase)*”, pero una vez serializado lo que nos devuelve es muy diferente, un string, “*string(59)*”, en este estado puedes entre otras cosas manipularlo como a cualquier string o almacenarlo en una base de datos para recuperarlo en otro momento. En el tercer vardump ya lo hemos deserializado y nos devuelve nuevamente un objeto tipo “object(MiClase)”.

Es aquí donde entra en juego _sleep() y _wakeup(). El método sleep sera invocado cuando pasemos el objeto por la función serialize, de esta forma podremos prepararlo para ser almacenado o para lo que queramos, como siempre el limite es la imaginación de cada cual y los posibles usos que se le pueden dar a esto son muchísimos. Hay que tener en cuenta que siempre ha de devolver un array, es preferible no usar sleep a hacer un return que no sea un array porque php dará un error. Veamos un ejemplo:

mensaje; } public function __sleep(){ $this->mensaje = 'He sido serializado'; return array('mensaje'); } } $mario = new Mario(); var_dump($mario); //Imprime: object(Mario)#1 (1) { ["mensaje"]=> string(18) "Hola, ¿que haces?" } $mario = serialize($mario); var_dump($mario); //Imprime: string(57) "O:5:"Mario":1:{s:7:"mensaje";s:19:"He sido serializado";}" $mario = unserialize($mario); var_dump($mario); //Imprime: object(Mario)#1 (1) { ["mensaje"]=> string(19) "He sido serializado" } $mario->diHola(); //Imprime: He sido serializado ?>

En el primer caso var_dump nos dice que le hemos pasado un objeto, en el segundo ya es un string, pero si nos fijamos ha desaparecido “Hola, ¿que haces?”, en el tercero ya hemos recuperado el objeto pero al llamar al método diHola() vemos que imprime “He sido serializado”. Realmente sencillo de usar, y si trabajas a menudo con bases de datos puede llegar a ser de los mas útil.

El método wakeup se encarga de realizar exactamente lo contrario que sleep, en el momento que deserializamos un objeto con unserialize se invoca a este método, para por ejemplo, restablecer la conexión con la base de datos, o alterar algún atributo. Probemos añadiendo wakeup a nuestro Mario para verlo mejor:

mensaje; } public function __sleep(){ $this->mensaje = 'He sido serializado'; return array('mensaje'); } public function __wakeup(){ $this->mensaje = 'ola k ase'; } } $mario = new Mario(); var_dump($mario); //Imprime: object(Mario)#1 (1) { ["mensaje"]=> string(18) "Hola, ¿que haces?" } $mario = serialize($mario); var_dump($mario); //Imprime: string(57) "O:5:"Mario":1:{s:7:"mensaje";s:19:"He sido serializado";}" $mario = unserialize($mario); var_dump($mario); //Imprime: object(Mario)#1 (1) { ["mensaje"]=> string(9) "ola k ase" } $mario->diHola(); //Imprime: ola k ase ?>

Se puede apreciar que los dos primeros var_dump devuelven resultados idénticos al ejemplo anterior, pero en el momento de usar unserialize el siguiente cambia, se ha llamado al método wakeup donde hemos añadido una linea para alterar el mensaje, de forma que se ha modificado lo que dice Mario, y al llamar al método diHola() el mensaje que nos devuelve es un “ola k ase”.