What is serialization in PHP

Valerio Barbera

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', '[email protected]');
$serializedUser = serialize($user);
echo $serializedUser;

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:"[email protected]";}

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; // [email protected]

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'];
    }
}

__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';
    }
}

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;

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";

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()
    {
        //
    }
}

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)
    {
        // ...
    }
}

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, 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: 

Related Posts

How to make Vite Hot Module Replacement work on Windows

As many of our community members already know, we recently started the renovation of the Inspector dashboard UI with a fresh new design and a modern technology stack. In this article I will explain why we decided to leave Webpack and embrace Vite as assets build tool and Hot Module Replacement. I will show you

Http traffic monitoring for Slim framework

This article follows the release of the first version of the monitoring library for Slim framework. Thanks to this package you can fully monitor the HTTP traffic against your application based on Slim. It takes less than one minute to get started. First let me give you a bit of context. Introducing the Slim framework

How to use wildcards in ExpressJs and Fastify monitoring libraries

With the booming software economy, the demand for new applications and software-defined automations is set to grow in the future years. Companies in any industry are creating software in the form of internal business tools, productivity tools, integrations, automations, and more. As a result, there is a need for tools that make it easy to

How to build scalable applications

Get the e-book about the Inspector scalability journey.