What is Serialization in Laravel

What is Serialization in Laravel

Posted on:September 22, 2023 at 10:00 PM

If you somehow wonder what exactly serialization which used at many places in laravel, this this post might help you. In this post, I would like to explain you what exactly it with a real life example. Therefore I assume it will be a easy for you to understand.

Table of Content

What is Serialization

Serialization, in the context of programming, refers to the process of converting a data structure or object state into a format that can be stored (like in a file or database) or transmitted (like over a network connection). Once the data is stored or transmitted, it can be deserialized back into its original structure or object. This process allows for the persistence of objects and data structures, as well as their transfer between systems.

In Laravel, serialization is commonly used in conjunction with jobs, events, and caching, especially when data needs to be persisted or passed to different parts of the system or even different systems entirely.

Real-life Example:

Imagine you have a toy (LEGO structure) that you’ve built. You want to send this toy to a friend who lives in another city. However, sending the fully assembled toy is risky because it might break. Instead, you decide to dismantle it and put each piece in its labeled bag, along with an instruction manual detailing how to reassemble it.

In this analogy:

  • Dismantling the toy is like serialization. You’re breaking down the object (toy) into a format (separate pieces in labeled bags) that’s easier to transport.
  • Reassembling the toy is like deserialization. You’re taking the transported format and reconstructing the original object.

Laravel and Serialization:

In Laravel, serialization is used in various scenarios:

  • Queued Jobs: When you dispatch a job to be queued, Laravel will serialize the job and its properties to store it in the queue system (e.g., database, Redis). When it’s time for the job to be processed, Laravel will deserialize the job to execute it.

Example: You want to send an email to a user. Instead of sending it immediately, you dispatch a job to send it later. The job, along with the user’s email information, gets serialized and stored in the queue. Later, a queue worker deserializes and processes the job, sending the email.

  • Caching: When you cache an object or data, Laravel might serialize it for storage. When retrieving it from cache, Laravel will deserialize it.

Example: You cache a complex configuration object because generating it is time-consuming. When caching, the object is serialized and stored. When you need the configuration again, it’s fetched from the cache and deserialized back into the original object.

  • Storing Sessions: Laravel may serialize user session data to store in session storage drivers like a file or database. When the session is read, it’s deserialized back into its original structure.

How serialize class looks like in laravel?

Let’s delve deep into a example trait called SerializesModels which has been using for each job in laravel.

<?php

namespace Illuminate\Queue;

use Illuminate\Queue\Attributes\WithoutRelations;
use ReflectionClass;
use ReflectionProperty;

trait SerializesModels
{
    use SerializesAndRestoresModelIdentifiers;

    /**
     * Prepare the instance values for serialization.
     *
     * @return array
     */
    public function __serialize()
    {
        $values = [];

        $reflectionClass = new ReflectionClass($this);

        [$class, $properties, $classLevelWithoutRelations] = [
            get_class($this),
            $reflectionClass->getProperties(),
            !empty($reflectionClass->getAttributes(WithoutRelations::class)),
        ];

        foreach ($properties as $property) {
            if ($property->isStatic()) {
                continue;
            }

            if (!$property->isInitialized($this)) {
                continue;
            }

            $value = $this->getPropertyValue($property);

            if ($property->hasDefaultValue() && $value === $property->getDefaultValue()) {
                continue;
            }

            $name = $property->getName();

            if ($property->isPrivate()) {
                $name = "\0{$class}\0{$name}";
            } elseif ($property->isProtected()) {
                $name = "\0*\0{$name}";
            }

            $values[$name] = $this->getSerializedPropertyValue(
                $value,
                !$classLevelWithoutRelations &&
                    empty($property->getAttributes(WithoutRelations::class))
            );
        }

        return $values;
    }

    /**
     * Restore the model after serialization.
     *
     * @param  array  $values
     * @return void
     */
    public function __unserialize(array $values)
    {
        $properties = (new ReflectionClass($this))->getProperties();

        $class = get_class($this);

        foreach ($properties as $property) {
            if ($property->isStatic()) {
                continue;
            }

            $name = $property->getName();

            if ($property->isPrivate()) {
                $name = "\0{$class}\0{$name}";
            } elseif ($property->isProtected()) {
                $name = "\0*\0{$name}";
            }

            if (!array_key_exists($name, $values)) {
                continue;
            }

            $property->setValue(
                $this,
                $this->getRestoredPropertyValue($values[$name])
            );
        }
    }

    /**
     * Get the property value for the given property.
     *
     * @param  \ReflectionProperty  $property
     * @return mixed
     */
    protected function getPropertyValue(ReflectionProperty $property)
    {
        return $property->getValue($this);
    }
}

In that example trait, you can see that it has following methods which actually reflects our lego example.

  • __serialize()
  • __unserialize()
  • getPropertyValue()

⚠️ Important Considerations:

Unserializing data from untrusted sources can be dangerous. It can lead to potential vulnerabilities. Laravel addresses this by signing serialized data in certain scenarios, but as a developer, always be wary of deserializing data you don’t trust.

In summary, serialization is a powerful tool that allows Laravel (and other frameworks/languages) to easily persist and transport data structures and objects. However, it’s essential to use it correctly and understand its implications.