PHP serialization and deserialization principles, and php serialization principles

Source: Internet
Author: User

PHP serialization and deserialization principles, and php serialization principles

0. Preface

Object serialization and deserialization are not described in detail. The serialization result in php is a php custom string format, a bit similar to json.

We need to solve several problems in designing Object serialization and deserialization in any language.

After an object is serialized, The serialized result has a self-describing function (the specific type of the object is known from the serialized result,

It is not enough to know the type. Of course, you also need to know the specific value of this type ).

Permission Control During serialization. You can customize serialized fields. For example, golang is very convenient.

Time performance problems: in some performance-sensitive scenarios, Object serialization cannot be slowed down, for example, high-performance services (I often use protobuf for serialization ).

Space performance problem: the serialized result cannot be too long. For example, if an int object in the memory is serialized and the data length is changed to 10 times the int length, the serialization algorithm is faulty.

This article only explains the serialization and deserialization processes in php from the perspective of php code ., remember that the serialization and deserialization operations only involve the data of objects, which should be easy to understand with object-oriented development experience.

1. serialize serialization and deserialization method unserialize

Php native provides object serialization functions, unlike c ++ ...... ^_^. It is also very simple to use, just two interfaces.

Class fobnn {public $ hack_id; private $ hack_name; public function _ construct ($ name, $ id) {$ this-> hack_name = $ name; $ this-> hack_id = $ id;} public function print () {echo $ this-> hack_name.PHP_EOL; }}$ obj = new fobnn ('fobnn ', 1 ); $ obj-> print (); $ serializedstr = serialize ($ obj); // serialize echo $ serializedstr through the serialize interface. PHP_EOL; $ toobj = unserialize ($ serializedstr); // deserialize $ toobj-> print () through unserialize ();
fobnnO:5:"fobnn":2:{s:7:"hack_id";i:1;s:16:"fobnnhack_name";s:5:"fobnn";}fobnn

The output in the second row is the serialized result. This structure is very understandable and can be found to be mapped by the object name/member name, of course, the serialized tag names of members with different access permissions are slightly different.

Based on the three questions I mentioned above, let's take a look.

1. Self-Description

O: 5: "fobnn": 2 where o indicates the object type and the type name is fobnn. in this format, 2 indicates that two Member objects exist.

The member object is also a set of sub-descriptions, which is a recursive definition.

The self-description function is mainly implemented by the string record object and member name.

2. Performance problems

The time performance of php serialization will not be analyzed in this article. For details, refer to the following section. However, the serialization result is similar to the protocol defined by json/bson. There is a protocol header, and the protocol header specifies the type, the Protocol body indicates the value corresponding to the type and does not compress the serialization result.

2. Magic methods in deserialization

Corresponding to the second problem mentioned above, php also has a solution. One is through magic, and the other is a custom serialization function. let's first introduce the magic methods _ sleep and _ wakeup.

class fobnn{ public $hack_id; private $hack_name; public function __construct($name,$id) {  $this->hack_name = $name;  $this->hack_id = $id; } public function print() {  echo $this->hack_name.PHP_EOL; } public function __sleep() {  return array("hack_name"); } public function __wakeup() {  $this->hack_name = 'haha'; }}$obj = new fobnn('fobnn',1);$obj->print();$serializedstr = serialize($obj);echo $serializedstr.PHP_EOL;;$toobj = unserialize($serializedstr);$toobj->print();
fobnnO:5:"fobnn":1:{s:16:"fobnnhack_name";s:5:"fobnn";}haha

Before serialization, _ sleep will be called to return an array of Member names to be serialized. In this way, we can control the data to be serialized. In this case, I only return hack_name, we can see that only hack_name members are serialized in the result.

After the serialization is complete, _ wakeup will be skipped. Here we can do some subsequent work, such as reconnecting to the database.

3. Custom Serializable Interface

interface Serializable {abstract public string serialize ( void )abstract public void unserialize ( string $serialized )}

Through this interface, we can customize the serialization and deserialization behaviors. This function can mainly be used to customize our serialization formats.

class fobnn implements Serializable{ public $hack_id; private $hack_name; public function __construct($name,$id) {  $this->hack_name = $name;  $this->hack_id = $id; } public function print() {  echo $this->hack_name.PHP_EOL; } public function __sleep() {  return array('hack_name'); } public function __wakeup() {  $this->hack_name = 'haha'; } public function serialize() {  return json_encode(array('id' => $this->hack_id ,'name'=>$this->hack_name )); } public function unserialize($var) {  $array = json_decode($var,true);  $this->hack_name = $array['name'];  $this->hack_id = $array['id']; }}$obj = new fobnn('fobnn',1);$obj->print();$serializedstr = serialize($obj);echo $serializedstr.PHP_EOL;;$toobj = unserialize($serializedstr);$toobj->print();
fobnnC:5:"fobnn":23:{{"id":1,"name":"fobnn"}}fobnn

After the custom serialization interface is used, our magic method is useless.

4. PHP dynamic type and PHP deserialization

Since the self-description function mentioned above saves the object type in the serialization result, and php is a dynamic type language, we can make a simple experiment.

class fobnn{ public $hack_id; public $hack_name; public function __construct($name,$id) {  $this->hack_name = $name;  $this->hack_id = $id; } public function print() {  var_dump($this->hack_name); }}$obj = new fobnn('fobnn',1);$obj->print();$serializedstr = serialize($obj);echo $serializedstr.PHP_EOL;;$toobj = unserialize($serializedstr);$toobj->print();$toobj2 = unserialize("O:5:\"fobnn\":2:{s:7:\"hack_id\";i:1;s:9:\"hack_name\";i:12345;}");$toobj2->print();

We modified the result of hack_name deserialization to int type, I: 12345

string(5) "fobnn"O:5:"fobnn":2:{s:7:"hack_id";i:1;s:9:"hack_name";s:5:"fobnn";}string(5) "fobnn"int(12345)

We can find that the object is successfully serialized! And can work normally !. Of course, this mechanism of php provides flexible and variable syntax, but it also introduces security risks. We will continue to analyze the security problems caused by php serialization and deserialization.

The above is all our knowledge about PHP serialization and deserialization principles. Thank you for your support to the customer's house.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.