CubicZ

导航

理解序列化与反序列化

该篇博客是在对于序列化和反序列化进行一个简单的基本的学习后,进行笔记整理对该知识点的理解与其基础要点,主要内容参考如下两篇文章。


参考链接:
https://www.freebuf.com/articles/web/167721.html

https://www.cnblogs.com/youyoui/p/8610068.html

0x01 序列化

php的序列化发生于存储或传递值过程中。

php序列化函数为:

string serialize(mixed $value)  // $value为要序列化的对象或数组

serialize()函数返回一个字符串,可以很方便的传递给其他需要该对象的地方,且其结构和类型不会改变。

 

实例:

<?php 
$sites = array('Google', 'Runoob', 'Facebook'); 
$serialized_data = serialize($sites); 
echo $serialized_data . PHP_EOL; 
?>

输出结果为:
a:3:{i:0;s:6:"Google";i:1;s:6:"Runoob";i:2;s:8:"Facebook";}

 

序列化格式:

String : s:size:value;
Integer : i:value;
Boolean : b:value;(保存1或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)}

序列化对象时,不会保留类中常量值,会保留父类中变量。

 

序列化中常见的魔法函数:

__construct() 创建对象时调用
__destruct() 销毁对象时调用
__toString() 当一个对象被当作一个字符串使用
__sleep() 在对象在被序列化之前运行
__wakeup 将在序列化之后立即被调用

 

选择对象序列化的变量

主要使用魔法方法:

public array __sleep( void )

* 若序列化对象时__sleep()魔术方法存在,则优先调用该方法,一般在类中通过重载该魔术方法进行使用
* 该方法返回值为一个数组,数组中为选择的应被序列化的对象变量
* 若不返回任何变量名,则序列化NULL,并报错
* 该方法不能返回父类的私有成员变量名,否则会报错,可用Serializable接口代替
* 常用于对大对象保存时进行清理工作,避免保存冗余数据

 

0x02 反序列化

序列化将对象作为字符串保存起来,同时PHP提供了反序列化函数:

mixed unserialize( string $str)

* 若字符串不可反序列化,则返回false并报错
* 若字符串可反序列化,则可为前文序列化格式中的类型
* 若反序列化后的变量为一个对象,则在重新构造对象后,php会检测是否有魔法函数__wakeup(),并尝试调用

 

0x03 序列化和反序列化用途

序列化和反序列化一般用作数据的缓存,如cookie、session缓存等。再例如,项目中一个class中存有一些变量,该class实例化后若一直不销毁,在使用过程中对其中变量会造成修改,当下一次调用它时,会浪费系统资源,于是即可将该对象序列化,作为字符串存储,等到要使用时再反序列化调用。

序列化和反序列化在Java中使用相对较多,即如json数据。
在PHP中使用的主要函数如下:
json_encode()
json_decode()

总而言之,序列化与反序列化即为将项目中的对象序列化为字节流,方便存储及调用。

 

至此,只是对于序列化与反序列化的基础认识及理解,之后会通过对一些反序列化漏洞的CTF例题进行研究,从而深入理解与学习反序列化。

posted on 2019-08-13 21:01  CubicZ  阅读(333)  评论(0编辑  收藏  举报