Monday, September 01, 2014

Serialization / Unserialization in PHP - III

We have already discussed how we can serialize/unserialize objects in PHP. Here we would see how we can achieve the same thing using the interface Serializable. 

To use this interface, we have to do away with the __wakeup() and __sleep() magic methods. So, the class implementing this interface does not need these magical functions to be defined. The Serializable interface has 2 abstract functions declared ( without their content body ) which means we must define their content body inside the class which implements this interface. These function have the following signatures :: 

// To get the String representation of our Object
abstract public string serialize ( void ) 

// To Construct our object back from the string

abstract public void unserialize ( string $serialized_data )

When the object needs to be serialized, the serialize() method is called. Similarly, when a new object ( of a particluar Class, and that Class Name is known as it (class name) was stored in the String Representation ) needs to be restored, the constructor __construct() is not automatically called; instead the unserialize() function is called as a working constructor. If we need to run the __construct(), we may call it explicitly ( self::__construct(); ) inside the unserialize() function.

So, let's check an example :

<?php
// Our class is implementing the
// Interface Serializable
class MyClass implements Serializable 
{
// Private Data
private $data1;
private $data2;

// Protected Data
protected $data3;
protected $data4;

// Public Data
public $data5;
public $data6;


// Constructor called
public function __construct()
{
   echo "<br> Constructor called";
 $this->data1 = "100";  
   $this->data2 = "200";  
   $this->data3 = "300";  
 $this->data4 = "400";  
 $this->data5 = "500";  
 $this->data6 = "600";  
 
 }

// Serialize function
public function serialize()
{
 echo "<br>Serialize called";
 
 // Return the serialized data
 return serialize(
    array( "data10" => $this->data1,
   "data20" => $this->data2,
"data30" => $this->data3,
"data40" => $this->data4,
"data50" => $this->data5,
"data60" => $this->data6,
 ));
}

// Unserialize function
public function unserialize($data)
{
 // We can call __construct explicitly
 // self::__construct();
 
 echo "<br>unSerialize called";
 
 // Unserialize
 $d = unserialize($data);
 
 // Re-Construct the Object
 $this->data1 = $d['data10'];
 $this->data2 = $d['data20'];
 $this->data3 = $d['data30'];
 $this->data4 = $d['data40'];
 $this->data5 = $d['data50'];
 $this->data6 = $d['data60'];
}

// display() function
function display()
{
  for($i=1;$i<=6;$i++)
    {
      echo "<br>" . $this->{"data$i"} ;
    }
 }

}

// Create a new Object

$obj = new MyClass;

// Serialize the Object

$ser = serialize($obj);

// Check the Serialize Data

var_dump($ser);

// Create new Object from Serialized data

$p   = unserialize($ser);

// Check the Object

var_dump($p);

// Call Public method on Object

$p->display();
?>

The code above is quite self-explanatory through its comments. Let's check out the output of the above code.

Constructor called
Serialize called
string 'C:7:"MyClass":144:{a:6:{s:6:"data10";s:3:"100";s:6:"data20";s:3:"200";s:6:"data30";s:3:"300";s:6:"data40";s:3:"400";s:6:"data50";s:3:"500";s:6:"data60";s:3:"600";}}' (length=164)

unSerialize called

object(MyClass)[2]
  private 'data1' => string '100' (length=3)
  private 'data2' => string '200' (length=3)
  protected 'data3' => string '300' (length=3)
  protected 'data4' => string '400' (length=3)
  public 'data5' => string '500' (length=3)
  public 'data6' => string '600' (length=3)

100

200
300
400
500
600

Let's analyse the output.

1. When $obj object was created, the respective constructor was called printing "Constructor called" on screen.
2. Next, when serialize() function is called upon the object $obj, the member method serialize() is called generating the message "Serialize called". 
3. The 3rd line in the output is the result of serialization of object properties. 
4. Next, we issue the statement $p = unserialize($ser); to unserialize the serialized data and create our new object $p. Hence "unSerialize called" message is displayed on screen.
5. var_dump( $p ) generates the couple of lines next, showing all the properties (and their values) within the object $p.
6. Next, when we call a public display() method in object $p, it iterates through all the properties inside the object and prints their values.