serialization

Serialization format

In PHP, serialization is used to store or pass PHP values without losing their type and structure.

The serialization function prototype is as follows:

string serialize ( mixed $value )Copy the code
Take a look at the following example:

class CC {
    public $data;
    private $pass;
 
    public function __construct($data.$pass)
    {
        $this->data = $data;
        $this->pass = $pass; }}$number = 34;
$str = 'uusama';
$bool = true;
$null = NULL;
$arr = array('a'= > 1,'b'= > 2);$cc = new CC('uu'.true);
 
var_dump(serialize($number));
var_dump(serialize($str));
var_dump(serialize($bool));
var_dump(serialize($null));
var_dump(serialize($arr));
var_dump(serialize($cc));Copy the code
The output is:

string(5) "i:34;"
string(13) "s:6:"uusama";"
string(4) "b:1;"
string(2) "N;"
string(30) "a:2:{s:1:"a"; i:1; s:1:"b"; i:2; }"
string(52) "O:2:"CC":2:{s:4:"data"; s:2:"uu"; s:8:" CC pass"; b:1; }"Copy the code
So serialization for different types of string format:

  • String : s:size:value;
  • Integer : i:value;
  • Boolean: b:value; (Save 1 or 0)
  • Null : N;
  • Array: a:size:{key definition; value definition; (repeated per element)}
  • Object: O:strlen(object name):object name:object size:{s:strlen(property name):property name:property definition; (repeated per property)}

Serialized object

From the above example, we can see that when serializing an object, only the attribute values are saved.

  • Will constants in objects be saved?
  • If it is inherited, will the variables of the parent class be saved
class CB {
    public $CB_data = 'cb';
}
 
class CC extends CB{
    const SECOND = 60;
 
    public $data;
    private $pass;
 
    public function __construct($data.$pass)
    {
        $this->data = $data;
        $this->pass = $pass;
    }
 
    public function setPass($pass)
    {
        $this->pass = $pass; }}$cc = new CC('uu'.true);
 
var_dump(serialize($cc));Copy the code
The output is:

string(75) "O:2:"CC":3:{s:4:"data"; s:2:"uu"; s:8:" CC pass"; b:1; s:7:"CB_data"; s:2:"cb"; }"Copy the code
Obviously, the value of a constant is not saved when an object is serialized. For variables in the parent class, they are retained.

Object serialization custom

When serializing objects, we do not need to save some sensitive attributes in the object. What about this?

When the serialize() function is called to serialize an object, it checks for the presence of a magic method __sleep() in the class. If it does, the method is called before the serialization operation is performed. You can override this method to customize the serialization behavior. The method prototype is as follows:

public array __sleep ( void )Copy the code
  • This method returns an array containing the names of all the variables in the object that should be serialized
  • The method returns nothing, NULL is serialized, and an E_NOTICE level error is generated
  • __sleep() cannot return the name of a private member of the parent class. Doing so produces an E_NOTICE level error. Only the Serializable interface can be used instead.
  • It is used to clean up large objects to avoid storing redundant data


class User{
    const SITE = 'uusama';
 
    public $username;
    public $nickname;
    private $password;
 
    public function __construct($username.$nickname.$password)
    {
        $this->username = $username;
        $this->nickname = $nickname;
        $this->password = $password; } // Override the serialization call method publicfunction __sleep() {// return the name of the variable to serialize, filtering out the password variablereturn array('username'.'nickname'); }}$user = new User('uusama'.'uu'.'123456');
var_dump(serialize($user));Copy the code
The result is as follows, apparently ignoring the value of the password field.

string(67) "O:4:"User":2:{s:8:"username"; s:6:"uusama"; s:8:"nickname"; s:2:"uu"; }"Copy the code

Serialized object store

As described above, we can serialize a copy of an object or data into a sequence string, and the value holder also preserves its structure.

We can store the serialized values in a file or cache. Not recommended to exist in the database, readability check, and not easy to migration maintenance, not easy to query.

$user = new User('uusama'.'uu'.'123456');
$ser = serialize($user); // Save local file_put_contents('user.ser'.$ser);Copy the code

deserialization

Method of use

We can serialize objects into strings and save them. How do we restore these serialized strings to their original form? PHP provides anti-sequence functions:

mixed unserialize ( string $str )Copy the code
The unserialize() deserialization function is used to convert a single serialized variable back to the VALUE of PHP.

  • If the string passed is not deserializable, FALSE is returned and an E_NOTICE is generated
  • Returns the converted value, which can be integer ‘ ‘float, string, array, or Object
  • If the deserialized variable is an object, PHP automatically attempts to call the __wakeup() member function (if it exists) after successfully reconstructing the object.
Look at the following example:

class User{
    const SITE = 'uusama';
 
    public $username;
    public $nickname;
    private $password;
    private $order;
 
    public function __construct($username.$nickname.$password)
    {
        $this->username = $username;
        $this->nickname = $nickname;
        $this->password = $password; } // Define the deserialized method called publicfunction __wakeup()
    {
        $this->password = $this->username; }}$user_ser = 'O:4:"User":2:{s:8:"username"; s:6:"uusama"; s:8:"nickname"; s:2:"uu"; } ';
var_dump(unserialize($user_ser));Copy the code
The output is:

object(User)# 1 (4) {
  ["username"]=>
  string(6) "uusama"
  ["nickname"]=>
  string(2) "uu"
  ["password":"User":private]=>
  string(6) "uusama"
  ["order":"User":private]=>
  NULL
}Copy the code
The following conclusions can be drawn:

  • The __wakeup() function is executed after the object is built, so $this->username is not empty
  • When deserializing, variable values are matched and copied to the serialized object as much as possible

Processing of undefined classes

In the above example, we defined the User class before calling the deserialization function unserialize(). What if we didn’t define it?

$user_ser = 'O:4:"User":2:{s:8:"username"; s:6:"uusama"; s:8:"nickname"; s:2:"uu"; } ';
var_dump(unserialize($user_ser));Copy the code
In this example, we did not define any User class, and the deserialization performed without error, resulting in the following result:

object(__PHP_Incomplete_Class)# 1 (3) {
  ["__PHP_Incomplete_Class_Name"]=>
  string(4) "User"
  ["username"]=>
  string(6) "uusama"
  ["nickname"]=>
  string(2) "uu"
}Copy the code
Note that in contrast to the result of the User class defined earlier, the deserialized object is __PHP_Incomplete_Class and specifies the class name of the undefined class.

If we use the deserialized unknown object at this point, E_NOTICE will be thrown. So look can not use is not the way, so how to deal with it? There are two options.

  • Define functions such as __autoload() that specify the class definition file toload when an undefined class is found
  • Unserialize_callback_func can be defined via php.ini, ini_set(), or.htaccess. It is called every time an undefined class is instantiated
The realization of the above two schemes is as follows:

// unserialize_callback_func available from PHP 4.2.0'unserialize_callback_func'.'mycallback'); // Set your callback functionfunction mycallback($classname) {// Just include the file with the class definition //$classname} // We recommend using the following function instead of __autoload() spl_autoload_register()function ($class_name) {// Dynamically load the definition file require_once for undefined classes$class_name . '.php';
});Copy the code

PHP predefined serialization interface Serializable

The __sleep() method cannot return the parent object, which implements the serialization interface Serializable.

The prototype of this interface is as follows:

Serializable {
    abstract public string serialize ( void )
    abstract public mixed unserialize ( string $serialized)}Copy the code
Note that if a class implements the Serializable interface, PHP will no longer call __sleep() and __wakeup() methods for serialization and deserialization.

class CB implements Serializable{

    public $CB_data = ' ';

    private $CB_password = 'ttt';

 

    public function setCBPassword($password)

    {

        $this->CB_password = $password;

    }

 

    public function serialize()

    {

        echo __METHOD__ . "\n";

        return serialize($this->CB_password);

    }

 

    public function unserialize($serialized)

    {

        echo __METHOD__ . "\n";

    }

}

 

class CC extends CB {

    const SECOND = 60;

 

    public $data;

    private $pass;

 

    public function __construct($data.$pass)

    {

        $this->data = $data;

        $this->pass = $pass;

    }

 

    public function __sleep() {// Outputs the method name calledecho __METHOD__ . "\n";

    }

 

    public function __wakeup() {// Outputs the method name calledecho __METHOD__ . "\n"; }}$cc = new CC('uu'.true);

$ser = serialize($cc);

var_dump($ser);

$un_cc = unserialize($ser);

var_dump($un_cc);

Copy the code
The running results are as follows:

CB::serialize
string(24) "C:2:"CC":10:{s:3:"ttt"; }"
CB::unserialize
object(CC)# 2 (4) {
  ["data"]=>
  NULL
  ["pass":"CC":private]=>
  NULL
  ["CB_data"]=>
  string(0) ""
  ["CB_password":"CB":private]=>
  string(3) "ttt"
}Copy the code
You can fully define the serialize() method, which returns the serialized value inside curly braces, as long as the rules for custom serialization and deserialization are consistent.

digression

In my opinion, serialization and deserialization is the idea of transferring abstract data. By defining rules for serialization and deserialization, we can serialize objects in PHP into byte streams and then transfer them to other languages or systems, which is very convenient in remote calls.

My official group click here to join the group chat [PHP Advanced Learning Exchange group 953224940], study together, discuss with each other. The group has been managed to organize the knowledge system (source code, learning video and other information), welcome to receive free.

Swoole is a fantastic PHP tutorial that is no slut on the market. PHP is as good a web developer as any other language, and Swoole makes it even better. Enter the communication, Internet of things industry to develop Baidu Map, Baidu order center, tiger tooth, zhanqi TV and so on! After the winter layoff period is the period of the expansion of the recruitment of large enterprises, now the market is flooded with primary programmers, advanced middle and senior programmers are absolutely the talent urgently needed by large enterprises, this learning course is suitable for those within 1-5 years of PHP developers are in a bottleneck period, want to break through their advanced middle and senior architects! Seats are limited, first come, first served!

Screenshots of some materials:







And limited-time premium benefits:

Tencent Senior PHP engineer written test topic

★ Deal with orders of 100 million level PV with high concurrency

★ Laravel develops tmall component services

Combat FLAG TV live video architecture project combat

Scan the qr code below to get it

Jumping (QR code automatically jumps)

For those who are interested in PHP backend technology and PHP architecture technology, my official group click here to learn and discuss with each other.

The group has been managed to organize the knowledge system (source code, learning video and other information), welcome to receive free.

This course is deeply standardized to Tencent T3-T4 standard, and builds a learning plan for web developers to advance middle and senior level and architects to improve technology, and for their own value-added and salary increase! If you join BAT special training camp, you can also get the quota and GO language learning permission!!

>>> Architect growth path