Serialización de objetos con PHP

Hoy tuve la necesidad de serializar objetos en PHP para implementar la funcionalidad de cache de las series basadas en los indicadores de un proyecto que estoy realizando y que, de paso, cada día me está quedando mas interesante.

Se me ocurrieron dos opciones, una fueron las funciones de serialización de objetos convencionales que incluye PHP y otra fue utilizar la representación JSON de mis datos para enviarlos y recibirlos de la persistencia, en este caso, archivos de texto.  Finalmente me decidí por utilizar las funciones de serialización sobre las de JSON por dos diferencias funcionales que en este proyecto eran ventajosas.

  • JSON sólo incluye a los atributos públicos, en mi caso eran protegidos.
  • Al recuperar la información en formato JSON y convertirla a objeto PHP nuevamente los datos son recuperados como objetos genéricos, no del tipo exacto como se codificaron.  Las funciones de serialización no tienen este problema.

Las funciones de serialización son muy simples: serialize y unserialize.

  • La primera de ellas recibe el objeto a serializar y retorna su representación en cadena.
    string serialize (mixed)
  • El segundo recibe la representación en cadena del objeto serializado y retorna el objeto PHP correspondiente.
    mixed unserialize (string)

Funcionan perfecto.  Todo fue demasiado sencillo.  Como siempre, en el mundo de Murphy, había un problema.  A los objetos que debía serializar el framework que utilizaba (Kohana) les estaba agregando un atributo protegido llamado db donde se encontraba la información de conexión a la base de datos, incluyendo la contraseña y por ende esta información estaba quedando serializada en mis archivos de caché!  Conclusión: un problema de seguridad terrible y un tamaño sensiblemente mayor para estos archivos.

Los objetos a serializar eran modelos con cierta complejidad de anidamiento de entidades (algunos atributos eran objetos también) por lo cual no era una opción muy interesante el realizar la serialización por mi mismo recorriendo recursivamente las estructuras de datos.  Tampoco pude acceder a los objetos para borrarles (unset) los atributos extra.

Por suerte las funciones de serialización incluyen una facilidad para estos casos.  Internamente se llaman automáticamente los métodos mágicos __sleep justo antes de la serialización y __wakeup justo después de la desserialización.

Mas interesante aún, el método __sleep puede retornar un arreglo con los nombres de los atributos que serán efectivamente incluídos en la serialización de los objetos de dicha clase.  Para remover entonces el atributo db de la serialización sólo tuve que hacer lo siguiente.

    public function __sleep()
    {
        $atributosSerializables = get_object_vars($this);
        unset($atributosSerializables['db']);
        return array_keys($atributosSerializables);
    }

11 thoughts on “Serialización de objetos con PHP”

  1. Hola! es la segunda vez en dias que caigo en tu blog buscando algo sobre POO 🙂 esta muy bueno lo que escribis y me es muy util.

    Donde vives? parece el America Central o el Caribe 🙂

    Saludos desde Argentina

  2. tambien de cordoba – argentina y caigo en tu blog buscando info de serialización en php, muy completo.

    Saludos.

      1. Ok, pero cuando hablamos de ajax, esto puede tener algún uso relevante, o que se le pueda dar un buen uso.

  3. Oscar, para la interacción con Ajax se utiliza también la serialización pero es mucho mas conveniente utilizarla con JSON: json_encode / json_decode.

    1. Entonces en que casos tu piensas que puede ser comveniente, tu lo explicaste arriba, pero en resumidas cuentas … donde tu le ves el potencial la serializacion de objetos en PHP. 😛 disculpa tanta preguntadera.

  4. Oscar, es útil en cualquier contexto donde requieras transmitir información que viene en un objeto sin necesidad de separar sus atributos antes de enviarla para reconstruírla nuevamente al recibirla. Al ser una cadena puede enviarse por ejemplo a través de Sockets o AJAX y almacenarse en archivos de texto plano. Si mal no recuerdo en esa época lo utilicé para crear un caché de las series de datos de unos indicadores que eran muy pesados para estarlos calculando con demasiada frecuencia.

    1. Yo utilize Stored Procedures para estar calculando indicadores que eran muy pesados.
      Primero ejecutaba los stored procedures, luego así generaba los reportes en crystal reports desde las tablas donde se generaban los datos de los indicadores.
      Pero la idea de utilizar la serialización en PHP es muy útil. Saludos.

Leave a Reply

Your email address will not be published. Required fields are marked *