php序列化与反序列化

0x00 序列化与反序列化

序列化(serialization),在计算机科学的数据处理中,是指将数据结构或对象状态转换成可取用格式(例如存储为文件,存储于缓冲,或经由网络中发送),以留待后续在相同或另一台计算机环境中,能回复原先状态的过程。

可以理解为,序列化是将变量转换为可保存或可传输的字符串的过程。

而反序列化就是在适当的时候把这个字符串转化为变量的过程。

序列化,也就是serialize()函数将一个对象转换成字符串时,其返回的字符串有着一定的规则。举例如下:

O:9:"democlass":3:{s:4:"name";s:4:"John";s:3:"sex";}

O代表object,还有一种情况,A代表数组。

9代表对象名称占9个字符,也就是democlass。

3代表对象里面有3个变量。

{}中的s代表string,也就是变量数据类型。

{}中的数字代表相应对象名称所占的字符数量。

0x01 序列化中字母类型的解释

a array
b boolean
d double
i integer
o common object
r reference
s string
C custom object
O class
N null
R pointer reference
U unicode string

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0x02 序列化示例

<?php
    class demo
    {
        private $test = "test";
        public $a = "111";
        static $b = "222";
    }
    $demo = new demo;
    $data = serialize($demo);
    $data1 = urlencode($data);
    echo $data;
    echo "
";
    echo $data1;
?>

这个的输出是

O:4:"test":2:{s:10:"demotest";s:4:"test";s:1:"a";s:3:"111";}
O%3A4%3A%22demo%22%3A2%3A%7Bs%3A10%3A%22%00demo%00test%22%3Bs%3A4%3A%22test%22%3Bs%3A1%3A%22a%22%3Bs%3A3%3A%22111%22%3B%7D

变量$test为private私有的,所以当序列化输出时:1、test变量就要加上类名demo,因此属性名为demotest。2、属性值为test。

变量$a为public公共的,所以当序列化输出时:1、属性名为a。2、属性值为111。

变量$b为static静态的,所以当序列化输出时,会忽略掉这个变量。

注:这里可以知道demotest的长度为8,但是序列化却显示长度为10。这是因为test变量是private属性,它会在序列化字符串的两侧加入空字节%00。(这里的第二行输出只是对符号进行了url编码,字母和数字不变)

0x03 反序列化示例

<?php
    $str = "O%3A4%3A%22demo%22%3A2%3A%7Bs%3A10%3A%22%00demo%00test%22%3Bs%3A4%3A%22test%22%3Bs%3A1%3A%22a%22%3Bs%3A3%3A%22111%22%3B%7D";
    $data = urldecode($str);
    $obj = unserialize($data);
    var_dump($obj);
?>

输出结果为

object(__PHP_Incomplete_Class)#1 (3) {
  ["__PHP_Incomplete_Class_Name"]=>
  string(4) "demo"
  ["test":"demo":private]=>
  string(4) "test"
  ["a"]=>
  string(3) "111"
}

暂时就先这样吧。