What is serialization in PHP

Valerio - Jan 2 '23 - - Dev Community

In PHP, serialization is the process of converting a data structure or object into a string representation that can be stored or transmitted. This allows you to save the state of an object or data structure to a database, cache, or send it over a network connection, and then later recreate the object or data structure from the serialized string.

Here is an example of how to serialize an object in PHP:

class User
{
    public $name;
    public $email;

    public function __construct($name, $email)
    {
        $this->name = $name;
        $this->email = $email;
    }
}

$user = new User('John', 'john@example.com');

$serializedUser = serialize($user);

echo $serializedUser;
Enter fullscreen mode Exit fullscreen mode

The output of this code would be a string representation of the $user object, similar to this:

O:4:"User":2:{s:4:"name";s:4:"John";s:5:"email";s:17:"john@example.com";}
Enter fullscreen mode Exit fullscreen mode

The serialization format in PHP is fairly simple. The serialized string consists of a series of data types and values, each separated by a colon. For example, the serialized string for an integer would be i:123, while the serialized string for a string would be s:5:"Hello".

To unserialize this string back into its original form, you can use the unserialize() function:

$unserializedUser = unserialize($serializedUser);

echo $unserializedUser->name; // John
echo $unserializedUser->email; // john@example.com
Enter fullscreen mode Exit fullscreen mode

Hooks in serialization and unserialization processes

There are two hooks available in PHP to interact with this process. These hooks allow you to define custom functions that will be called when an object is serialized or unserialized. This can be useful for performing custom actions when an object is serialized or unserialized, such as logging or validation.

__sleep() hook: This hook is called during serialization, before an object’s properties are serialized. It allows developers to specify which properties should be serialized and which should be excluded.

class MyClass 
{
    private $data;
    private $secret;

    public function __sleep() {
        return ['data'];
    }
}
Enter fullscreen mode Exit fullscreen mode

__wakeup() hook: This hook is called during unserialization, after an object’s properties have been unserialized. It allows developers to perform any necessary initialization or setup on the object after it has been unserialized.

class MyClass 
{
    private $data;
    private $secret;

    public function __wakeup() {
        $this->secret = '123456';
    }
}
Enter fullscreen mode Exit fullscreen mode

How to use serialization to communicate with external services

To use serialization to communicate with external services, you can use PHP’s built-in functions for sending HTTP requests, such as file_get_contents() or curl_exec(). You can then pass the serialized data as a parameter in the request, and the external service can unserialize the data on its end to access the information.

Here's an example of using serialization to send data to an external service:

$data = [
    "name" => "John", 
    "age" => 30
];

// Serialize the data
$serializedData = serialize($data);

// Send the serialized data to the external service using HTTP POST
$ch = curl_init("http://example.com/service");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "data=" . $serializedData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

// Handle the response from the service
echo $response;
Enter fullscreen mode Exit fullscreen mode

On the external service, you would then use the unserialize() function to convert the serialized data back into a PHP data structure or object.

// Get the serialized data from the HTTP POST request
$serializedData = $_POST['data'];

// Unserialize the data
$data = unserialize($serializedData);

// Use the data
echo "Name: " . $data['name'] . "\n";
echo "Age: " . $data['age'] . "\n";
Enter fullscreen mode Exit fullscreen mode

A practical example of serialization – Laravel Queue

The first time I needed to delve into this topic was because of the Laravel Queue system.

If you want to learn more about our implementation of the Laravel Queue system, you can read this article: https://inspector.dev/what-worked-for-me-using-laravel-queues-from-the-basics-to-horizon/

When Laravel store a Job class into the queue service (which can be Redis, AWS SQS, or similar) the object is serialized. When you create a new Job class in Laravel it ships with the SerializesModels trait included.

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;

class ExampleJob implements ShouldQueue
{
    use Dispatchable;
    use InteractsWithQueue;
    use Queueable;
    use SerializesModels;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //
    }
}
Enter fullscreen mode Exit fullscreen mode

If your job class contains references to Eloquent models, this trait allows you to customize the serialization process. It contains an implementation of the hooks seen above:

namespace Illuminate\Queue;

trait SerializesModels
{
    use SerializesAndRestoresModelIdentifiers;

    /**
     * Prepare the instance for serialization.
     *
     * @return array
     */
    public function __sleep()
    {
        // ...
    }

    /**
     * Restore the model after serialization.
     *
     * @return void
     */
    public function __wakeup()
    {
        // ...
    }

    /**
     * Prepare the instance values for serialization.
     *
     * @return array
     */
    public function __serialize()
    {
        // ...
    }

    /**
     * Restore the model after serialization.
     *
     * @param  array  $values
     * @return void
     */
    public function __unserialize(array $values)
    {
        // ...
    }
}
Enter fullscreen mode Exit fullscreen mode

As mentioned in the Laravel documentation:

If your queued job accepts an Eloquent model in its constructor, only the identifier for the model will be serialized onto the queue. When the job is actually handled, the queue system will automatically re-retrieve the full model instance and its loaded relationships from the database. This approach to model serialization allows for much smaller job payloads to be sent to your queue driver.

But there may also be side effects to watch out for. For example the record could be modified by other processes before the Job is executed. So you always have to take in consideration the asynchronous nature of this architecture.

Serialization interoperability

serialize() and unserialize() was PHP's default serialization technique. They are used to transfer PHP objects to external services but they are strictly coupled with PHP specifications.

In fact, there are many libraries in other programming languages that allow you to serialize objects and data structures according to the PHP standard, like this one in Java just for example:

https://github.com/marcospassos/java-php-serializer

An alternative to this specific format you can use the JSON standard to transfer data to external services without worrying about the technology with which the recipient service is developed. PHP supports this kind of serialization through the two functions: json_encode and json_decode.

Monitor your PHP application for free

Do you want to monitor how your users experience your application?

For example, how much time does it take to load a page? Is an API endpoint broken? Are there any database errors?

In order to answer these kinds of questions consider trying Inspector, a Code Execution Monitoring tool built for developers.

With Inspector you don't need to install anything at the server level. It works with a simple composer package.

Check out our GitHub account for all supported languages or follow this tutorial to add real-time monitoring to your Laravel application:

Laravel Application Monitoring with a simple package

Laravel monitoring. Inspector is a code monitoring tool designed for Laravel developers. Try the Laravel package for free!

favicon inspector.dev
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .