We studied in previous articles the magiques__clone () methods, __set (), __get () and __call (). PHP adds to recent two additional magic methods __sleep () and __wakeup () that allow overloading the native process of serialization and de-serialization of PHP data. That’s what we’ll explain in tutorial with some concrete examples and easy to understand.
We’ll be covering the following topics in this tutorial:
What is data serialization?
To summarize very simply, action to serialize a variable is to convert it into a string for example, store it in a text file. Conversely, the action of deserializing a string is to apply the inverse process to recover the original variable. This process is not limited to PHP, you will find it in many languages like Java, ActionScript, C, C # … to name a few.
The words serialization and de-serialization are probably the most common words, but you will hear / maybe read somewhere the words linearization / delinearization or even marshalling / unmarshalling. Serialize, linearized, marshaller (deserialize, respectively, and delinearize unmarshaller) define the concepts of serialization and de-serialization.
Syntactically speaking, data serialization is reflected by using the serialize () function, the inverse action results unserialize (). Let’s see some examples.
Serialization / deserialization of an integer variable
<? php
$ iVar = 1;
$ sSerialized = serialize ($ iVar);
$ iUnserialized = unserialize ($ sSerialized);
echo '<pre>';
var_dump ($ sSerialized, $ iUnserialized);
echo '</ pre>';
?>
The first var_dump () displays the following string to standard output:
string (4) “i: 1;”
And the second displays the following:
int (1)
You deduce course it is not interesting to serializer an integer since you can store it directly. However, this example is still useful to a simple principle illustration: a variable serialization preserves type it. So we will have a good return integer, just as we retain an Array or an object.
Serialization / de-serialization of an array (Array)
Consider now a table as an example. Serialization and deserialization here become much more interesting since they will allow us to transform (and recover) an entire table.
<? php
$ atable = array ('Moga', 'Agra', 'Abohar', 'Punjab', 'Jaipur');
$ sSerialized = serialize ($ atable);
$ aUnserialized = unserialize ($ sSerialized);
echo '<pre>';
var_dump ($ sSerialized, $ aUnserialized);
echo '</ pre>';
?>
The first var_dump displayed:
string (87) "a: 5: {i: 0; s: 4:" Moga"; i: 1; s: 4:"Agra"; i: 2; s: 6:"Abohar"; i: 3; s: 6: "Punjab"; i: 4; s: 6: "Jaipur";} "
Serialization of the table eventually built a character string with a length of 87 characters. Let us quickly the structure of this chain.
• The first character of the string indicates the type of the serialized variable. Here, the letter “a” thus indicates that we have to serialize an array (array).
• Then we read the number 5 indicates the number of elements in the array. In between parentheses, we find all the elements of the array.
• The first letter of an element group indicates the type of the index in the table followed by its value. Here we have an array indexed numerically serialized, so
each index is an integer (“i”) whose value is between 0 and 4 inclusive. If we had used an associative array, the indexes would have become strings (“s”).
• We then read each stored value, type (“s”), its length (4) and the value stored in the table (“City”).
With all this information, the unserialize () function is able to completely rebuild the array by analyzing the formatted string.
This is why the second var_dump () displays the result in which we find all the information in the serialized string:
array(5) {
[0]=>
string(4) "Moga"
[1]=>
string(4) "Agra"
[2]=>
string(6) "Abohar"
[3]=>
string(6) "Punjab"
[4]=>
string(6) "Jaipur"
}
Now try to serialize / deserialize an object.
Serialization and de-serialization of an object
Now comes the most interesting example, serialization of an object. Let’s take a basic class with different properties. We deliberately use public property, private and protected in order to visualize how does serialization of an object with different properties.
<? php
class Sleeper {
protected $ _age;
protected $ _HeadCap;
private $ _FavoriteColor;
public $ _tastes ;
public function __construct () {
$ this -> _age = 19;
$ this -> _HeadCap = true;
$ this -> _FavoriteColor = 'red';
$ this -> _tastes = array ('Music', 'cinema', 'curling');
}
}
?>
We then get the following results respectively:
string (181) "O: 7:" Sleeper ": 4: {s: 7:" * _age "; i: 19; s: 14:" * _HeadCap"; b: 1; s: 25:"FavoriteColor";s:6:"_tastes";a:3:
{i:0;s:7:"Music";i:1;s:7:"cinema";i:2;s:7:"curling";}}
object (Sleeper) # 2 (4) {
["_age: protected"] =>
int (19)
["_HeadCap: protected"] =>
bool (true)
["_FavoriteColor: private"] =>
string (5) "Red"
["_tastes"] =>
array (3) {
[0] =>
string (7) "music"
[1] =>
string (7) "cinema"
[2] =>
string (7) "curling"
}
}
You already know that the type variable was preserved, it is the same for visiblity (private, protected and public), it does not change in any way the class structure. We Instance Storage talking, we must be careful that your class is declared before serialization, otherwise you’ll get an error:
Fatal error: Class ‘Sleeper’ not found in /home/path/to/your/script.php on line xx
You will notice the “o” as the first character of the serialized chain to say we have much to serialize an object.
Magic Methods __sleep () and __wakeup ()
Now that we have understood the principle of serialization, we can enter the heart of the matter and talk about the magic methods __sleep () and __wakeup ().
These methods will be respectively called by the script when using serialize () and unserialize (). Here is a demonstration, we will add __sleep () and _wakeup () to our Sleeper.
The magic __sleep () method, however, must take an action that serialization is going well. It is here that one can see the first benefit of the serialization of a class instance: you select which properties of your body you want to store. To do this, the __sleep () method must return an array containing the names of the properties to keep:
<? php
class Sleeper {
/ **
* Magic Method __sleep () Called during a serialize ()
*
*return Array the list of parameters to be held
* /
public function __sleep() {
echo 'Bon ben I'm going to sleep.';
return array ('_age', '_HeadCap', '_FavoriteColor');
}
/ **
* Magic Method __wakeup () Called during a unserialize ()
*
*return Void
* /
public function __wakeup() {
echo 'ben good I'm going to get a coffee.';
}
}
?>
Here one chooses to keep that age Sleeper, her favorite color and whether or not he has his cap on his head.
By executing the above code again, you’ll see both echo appear after (“Bon ben I’ll sleep.” Then “ben good I’m going to get a coffee.”) Confirming that the methods __sleep () and __wakeup () have been successively called.
The result of the serialization is:
string (108) “O:7:”Dormeur”:3:{ s: 7 : “*_age” ;i :19 ;s: 14: “* _HeadCap “;b:1;s:25 : ” FavoriteColor “;s:5:”tastes”;}”
We see that we do not keep the likes of Sleeper. And here is what you show the second var_dump:
object (Sleeper) # 2 (4) {
["_age: protected"] =>
int (19)
["_HeadCap: protected"] =>
bool (true)
["_FavoriteColor: private"] =>
string (5) "Red"
["_tastes"] =>
NULL
}
Note that only the properties specified in the __sleep () have been stored, the “_tastes” property, meanwhile, is equal to NULL, its contents has not been preserved. Of course, the interest does not stop there, you will be able to perform the actions you want from these methods: synchronization with a database, close a connection to a database when serializing, reopen at deserialization, etc.
For lovers of DIY, it is also possible to implement the concept of “cast” of object, PHP totally absent at present.