Usando __wakeup() en PHP 7

El tema de los objetos serializables no estaría completo sin la contraparte del método serialize(): el método unserialize(). Si la llamada al método serialize() activa el método mágico __sleep() del objeto, es lógico esperar que haya un comportamiento similar para la deserialización. Con razón, llamando al método unserialize() sobre un objeto dado activa su método mágico __wakeup().


El uso previsto de __wakeup() es restablecer cualquier recurso que se haya perdido durante la serialización y realizar otras tareas de reinicialización.

Echemos un vistazo al siguiente ejemplo:

<?php
class Backup
{
protected $ftpClient;
protected $ftpHost;
protected $ftpUser;
protected $ftpPass;
public function __construct($host, $username, $password)
{
$this->ftpHost = $host;
$this->ftpUser = $username;
$this->ftpPass = $password;
echo 'TEST!!!' . PHP_EOL;
$this->connect();
}
public function connect()
{
$this->ftpClient = ftp_connect($this->ftpHost, 21, 5);
ftp_login($this->ftpClient, $this->ftpUser, $this->ftpPass);
}
public function __sleep()
{
return ['ftpHost', 'ftpUser', 'ftpPass'];
}
public function __wakeup()
{
$this->connect();
}
}
$backup = new Backup('test.rebex.net', 'demo', 'password');
$serialized = serialize($backup);
$unserialized = unserialize($serialized);
var_dump($backup);
var_dump($serialized);
var_dump($unserialized);

La clase Backup acepta información de host, nombre de usuario y contraseña a través de su constructor. Internamente, establece la función principal de ftp_connect() de PHP para establecer una conexión hacia el servidor FTP. Una conexión establecida con éxito devuelve un recurso que almacenamos en una propiedad protegida $ftpClient de una clase. Como los recursos no son serializables, nos aseguramos de excluirlos de la matriz de retorno del método __sleep(). Esto asegura que nuestra cadena serializada no contenga la propiedad $ftpHost. Tenemos a $ this-> connect (); que llame dentro del método __wakeup () para reinicializar el recurso $ ftpHost. El ejemplo general da como resultado el siguiente resultado:

object(Backup)#1 (4) {
["ftpClient":protected]=> resource(4) of type (FTP Buffer)
["ftpHost":protected]=> string(14) "test.rebex.net"
["ftpUser":protected]=> string(4) "demo"
["ftpPass":protected]=> string(8) "password"
}
string(119)
"O:6:"Backup":3:{s:10:"ftpHost";s:14:"test.rebex.net";s:10:"ftpUser";s:4:
"demo";s:10:"*ftpPass";s:8:"password";}"
object(Backup)#2 (4) {
["ftpClient":protected]=> resource(5) of type (FTP Buffer)
["ftpHost":protected]=> string(14) "test.rebex.net"
["ftpUser":protected]=> string(4) "demo"
["ftpPass":protected]=> string(8) "password"
}

El método __wakeup() toma el rol de constructor durante la llamada a la función unserialize(). Debido a que el método __construct() del objeto no se llama durante la deserialización, debemos tener cuidado de implementar la lógica necesaria del método __wakeup() para que el objeto pueda reconstruir cualquier recurso que pueda necesitar.

Comparte