Menu
Coddy logo textTech

__serialize y __unserialize

Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy — lección 49 de 91.

Cuando necesitas convertir un objeto en una cadena para su almacenamiento o transmisión, PHP utiliza la serialización. Los métodos mágicos __serialize() y __unserialize() te dan control sobre exactamente qué datos se guardan y cómo se restauran.

El método __serialize() devuelve un array de datos para ser serializados, mientras que __unserialize() recibe ese array y reconstruye el objeto:

<?php
class Session {
    public function __construct(
        private string $userId,
        private array $data,
        private int $createdAt
    ) {}
    
    public function __serialize(): array {
        return [
            'userId' => $this->userId,
            'data' => $this->data
        ];
    }
    
    public function __unserialize(array $data): void {
        $this->userId = $data['userId'];
        $this->data = $data['data'];
        $this->createdAt = time();
    }
    
    public function getCreatedAt(): int {
        return $this->createdAt;
    }
}

$session = new Session("user123", ["theme" => "dark"], time());
$serialized = serialize($session);

$restored = unserialize($serialized);
echo "User: " . $restored->getCreatedAt();

Observa cómo createdAt se excluye de la serialización y obtiene una nueva marca de tiempo al ser deserializado. Esto es útil para excluir datos sensibles, valores temporales o recursos que no se pueden serializar, como las conexiones a bases de datos.

Estos métodos reemplazaron a los antiguos métodos __sleep() y __wakeup() en PHP 7.4, ofreciendo un enfoque más limpio donde trabajas directamente con arreglos de datos en lugar de nombres de propiedades.

challenge icon

Desafío

Fácil

Vamos a construir un sistema de almacenamiento en caché de perfiles de usuario que demuestre cómo __serialize() y __unserialize() te dan el control sobre qué datos se guardan y cómo se restauran.

Organizarás tu código en dos archivos:

  • UserProfile.php — Crea una clase UserProfile que represente el perfil de un usuario con capacidades de almacenamiento en caché. Usa la promoción de constructor para definir propiedades privadas para $userId (string), $username (string), $email (string) y $accessToken (string). Añade una propiedad privada $cachedAt que almacene cuándo se guardó el perfil en caché (establécela como "not cached" inicialmente en el constructor). Tu clase necesita:
    • __serialize() — Devuelve un array que contiene solo el userId, username y email. El accessToken es sensible y nunca debe ser serializado. La marca de tiempo cachedAt se regenerará al restaurar.
    • __unserialize() — Restaura el userId, username y email desde el array de datos. Establece accessToken como "expired" (ya que los tokens no deben persistir).
    • getInfo() — Devuelve un string con el formato: "[username] ([email]) - Token: [accessToken] - Cached: [cachedAt]"
  • main.php — Incluye el archivo UserProfile. Recibirás cuatro entradas: un ID de usuario, un nombre de usuario, un correo electrónico y un token de acceso. Crea una instancia de UserProfile con estos valores. Imprime tres líneas:
    • La información del perfil original (antes de la serialización)
    • Serializa el perfil usando serialize(), luego des-serialízalo usando unserialize() para crear un perfil restaurado. Imprime la información del perfil restaurado.
    • Imprime "Token preserved: yes" o "Token preserved: no" dependiendo de si el token del perfil restaurado coincide con el original (pista: no debería coincidir ya que los tokens expiran al restaurar)

Este patrón es esencial para almacenar datos de usuario en caché de forma segura: quieres guardar la información del perfil pero nunca persistir credenciales sensibles como los tokens de acceso. Cuando el perfil se restaura desde la caché, el token se marca como expirado, obligando a la aplicación a obtener uno nuevo.

Hoja de referencia

Los métodos mágicos __serialize() y __unserialize() controlan qué datos se guardan durante la serialización y cómo se restauran los objetos.

__serialize() devuelve un array de datos para ser serializados:

<?php
public function __serialize(): array {
    return [
        'userId' => $this->userId,
        'data' => $this->data
    ];
}

__unserialize() recibe el array y reconstruye el objeto:

<?php
public function __unserialize(array $data): void {
    $this->userId = $data['userId'];
    $this->data = $data['data'];
    $this->createdAt = time();
}

Usa serialize() para convertir un objeto en una cadena y unserialize() para restaurarlo:

<?php
$serialized = serialize($session);
$restored = unserialize($serialized);

Estos métodos son útiles para excluir datos sensibles, valores temporales o recursos que no se pueden serializar (como conexiones a bases de datos). Las propiedades pueden regenerarse con valores frescos durante la deserialización.

Pruébalo tú mismo

<?php

require_once 'UserProfile.php';

// Leer entradas
$userId = trim(fgets(STDIN));
$username = trim(fgets(STDIN));
$email = trim(fgets(STDIN));
$accessToken = trim(fgets(STDIN));

// TODO: Crear una instancia de UserProfile con los valores de entrada

// TODO: Imprimir la información del perfil original (antes de la serialización)

// TODO: Serializar el perfil, luego deserializarlo para crear un perfil restaurado

// TODO: Imprimir la información del perfil restaurado

// TODO: Imprimir "Token preserved: yes" o "Token preserved: no"
// dependiendo de si el token del perfil restaurado coincide con el original

?>
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos