Backend Development

PHP Magic Methods Difference Between __sleep and __serialize

PHP Magic Methods Difference Between __sleep and __serialize

Two important magic methods in PHP used when storing objects in serialized form in database which are the __sleep and __serialize.

 

 

When serializing objects in PHP using serialize() and unserialize(), you can control how the object is serialized with the magic methods __sleep() and __serialize(), so let’s talk about __sleep() first.

 

Using __sleep()

The __sleep() method is invoked automatically if you try to serialize the object with the serialize() php function. It should return an array with the property names that should be serialized. If the method doesn’t return anything, then null is serialized and php will trigger an E_NOTICE error.

The purpose of this method is to limit the properties that should be serialized in large objects with many properties.

This example inspired from Laravel framework for serializing email classes:

Without __sleep:

<?php
class ActivationEmail
{
    public $username;

    public $email;

    protected $activationKey;
    
    public function __construct($username, $email, $activationKey)
    {
        $this->username = $username;
        $this->email = $email;
        $this->activationKey = $activationKey;
    }
    
    private function render()
    {
        // render html template
        echo "<html>...</html>";
    }
}

$conn = new ActivationEmail("john", "user@example.com", "random key");
$serialized = serialize($conn);
echo $serialized;

// output
O:15:"ActivationEmail":3:{s:8:"username";s:4:"john";s:5:"email";s:16:"user@example.com";s:16:"*activationKey";s:10:"random key";}

With __sleep:

<?php
class ActivationEmail
{
    public $username;

    public $email;

    protected $activationKey;
    
    public function __construct($username, $email, $activationKey)
    {
        $this->username = $username;
        $this->email = $email;
        $this->activationKey = $activationKey;
    }
    
    private function render()
    {
        // render html template
        echo "<html>...</html>";
    }
    
    public function __sleep()
    {
        return array('email', 'activationKey');
    }
}

$conn = new ActivationEmail("john", "user@example.com", "random key");
$serialized = serialize($conn);
echo $serialized;


// output
O:15:"ActivationEmail":2:{s:5:"email";s:16:"user@example.com";s:16:"*activationKey";s:10:"random key";}


?>

As shown here in the first example without using __sleep() all class properties is returned in the serialized object. However in the second example after using __sleep() only the “email” and “activationKey” properties returned.

Now let’s check the __serialize() method.

 

Using __serialize()

The __serialize() method seems similar to __sleep() in the fact that it’s invoked when calling serialize() function in objects. However __serialize() change the serialized form of the object by returning an associative array the key/value pairs of the properties you need to serialize.

<?php
class ActivationEmail
{
    public $username;

    public $email;

    protected $activationKey;
    
    public function __construct($username, $email, $activationKey)
    {
        $this->username = $username;
        $this->email = $email;
        $this->activationKey = $activationKey;
    }
    
    private function render()
    {
        // render html template
        echo "<html>...</html>";
    }
    
    public function __serialize()
    {
    	return array(
    		"user" => $this->username,
    		"email" => $this->email,
    		"key" => $this->activationKey
    	);
    }
}

$conn = new ActivationEmail("john", "user@example.com", "random key");
$serialized = serialize($conn);
echo $serialized;


// output
O:15:"ActivationEmail":3:{s:4:"user";s:4:"john";s:5:"email";s:16:"user@example.com";s:3:"key";s:10:"random key";}

?>

As you see in this example that i changed the key names in __serialize() in the returned serialized object.

Also you can omit certain properties from the serialized object as shown:

public function __serialize()
    {
    	return array(
    		"user" => $this->username,
    		"key" => $this->activationKey
    	);
    }

When using __serialize() and __sleep() together, the __serialize() is invoked and __sleep() will be ignored:

public function __serialize()
    {
    	return array(
    		"user" => $this->username,
    		"email" => $this->email,
    		"key" => $this->activationKey
    	);
    }

    public function __sleep()
    {
        return array("activationKey");
    }


// output
O:15:"ActivationEmail":3:{s:4:"user";s:4:"john";s:5:"email";s:16:"user@example.com";s:3:"key";s:10:"random key";}

If no array is returned in  __serialize() method then a TypeError will be triggered.

 

5 2 votes
Article Rating

What's your reaction?

Excited
1
Happy
2
Not Sure
0
Confused
0

You may also like

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments