目录
前言
在了解反序列化时,我们需要了解什么是序列化
序列化
序列化是计算机编程中一个重要的概念,它指的是将数据结构或对象状态转换为可以存储或传输的格式的过程。这种格式通常是二进制格式,但也可以是JSON、XML等文本格式。序列化使得数据可以持久化存储到磁盘上,或者通过网络传输到其他计算机。
以php为列
<?php
$a =new admin();
$b=serialize($a);
echo $b;
class admin{
public function __construct(){
echo "4";
}
public function __destruct()
{
echo "3";
}
public function __toString()//当对象被当作字符串来使用
{
return "2";
}
public function __wakeup() //在对象被反序列化后,对象激活前被立即使用
{
echo "1";
}
}
结果为4O:5:"admin":0:{}3
O:5:"admin"
表示这是一个对象,对象的类型是admin
,长度为 5(这通常是指对象的名称长度)。:0:{}
表示这个对象没有属性。
首尾各种出现4和3是因为构造函数和析构函数的原因
构造函数是一种特殊的方法,用于在创建对象时初始化对象的状态。在面向对象编程中,构造函数通常具有与类名相同的名称,并且没有返回类型。当使用
new
关键字创建类的新实例时,会自动调用构造函数。就是初始化对象的属性
析构函数是面向对象编程中的一个概念,用于在对象生命周期结束时进行清理工作。当对象不再被使用,需要释放其占用的资源时,如内存、文件句柄、网络连接等,就会调用析构函数。在对象生命结束时候执行结束的状态工作
但我们添加了一个$a的public属性,序列化后原来的"admin":0->"admin":1就变成了1,说明adimin这个类有一个属性1:{s:1:"a";i:5;}后面是说明s:1,其中a属性就占用一个名称,i为其数据类型为整型,且数值为5
在对序列化有一定了解后我们来了解反序列化
反序列化
反序列化是序列化的逆过程,它涉及到将序列化后的数据(通常是存储在文件、数据库或通过网络传输的数据)转换回原始的编程语言数据结构或对象。这个过程可以理解为数据传输时候将数据序列化,然后再次解读其序列化后的数据转换为源数据
<?php
$a =new admin();
$b=serialize($a);
$c=unserialize($b);
echo $a;
class admin{
public $a=5;
public function __construct(){
echo "4";
}
public function __destruct()
{
echo "3";
}
public function __toString()//当对象被当作字符串来使用
{
return "2";
}
public function __wakeup() //在对象被反序列化后,对象激活前被立即使用
{
echo "1";
}
}
unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源 而
wakeup()
用于在从字符串反序列化为对象时自动调用。一个 PHP 对象被序列化成字符串并存储在文件、数据库或者通过网络传输时,我们可以使用unserialize()
函数将其反序列化为一个 PHP 对象。在这个过程中,PHP 会自动调用该对象的__wakeup()
方法,对其进行初始化。
__wakeup()
方法的作用是对一个对象进行一些必要的初始化操作。例如,如果一个对象中包含了一些需要进行身份验证的属性,那么在从字符串反序列化为对象时,就可以在__wakeup()
方法中进行身份验证。或者如果一个对象中包含了一些需要在每次初始化时计算的属性,也可以在__wakeup()
方法中进行计算允许程序恢复之前保存的状态,或者接收从其他系统发送的数据,并将其转换为可用的格式。在__wakeup()方法执行后,其对象被打印执行__toString()方法,最后销毁没被序列化的对象,再次销毁被反序列后的序列化对象,反序列化字符串
$b
。这将创建一个新的admin
类的实例$c,销毁的是两个实列,
从而出现了两个3
为什么出现反序列化和序列化?
通过序列化与反序列化我们可以很方便的在数据中进行对象的传递,本质便是方便数据的传输
序列化(Serialization)的作用:
-
持久化存储:将对象的状态转换为可存储的格式,如文件、数据库等,以便在程序关闭后仍能保存对象信息。
-
网络传输:将对象转换为字节流,通过网络发送到另一端,这在远程过程调用(RPC)和微服务架构中非常常见。
-
跨平台数据交换:序列化允许不同平台和不同编程语言之间交换数据,只要它们能够解析相同的序列化格式。
-
对象克隆:通过序列化和反序列化,可以创建对象的深拷贝,即创建一个对象的完整副本,包括其所有属性和嵌套对象。
-
内存管理:在某些情况下,序列化可以用于优化内存使用,例如,将不常用的对象序列化到磁盘,从而减少内存占用。
-
版本控制:序列化时可以包含对象的版本信息,有助于处理版本兼容性问题。
-
安全性:序列化可以结合数据签名等安全措施,确保数据的完整性和防止未授权的反序列化。
反序列化(Deserialization)的作用:
-
恢复对象状态:从持久化存储中读取序列化的数据,并将其转换回原始对象,恢复其状态。
-
接收网络数据:在网络通信中,接收端需要将接收到的序列化数据反序列化,以获得发送端传递的对象。
-
跨语言数据使用:当使用不同编程语言的系统需要共享和使用数据时,反序列化允许将序列化的数据转换为当前语言可以使用的对象。
-
实现对象的动态创建:反序列化可以根据序列化数据动态创建对象,而无需在代码中显式编写对象创建逻辑。
-
测试和调试:反序列化可以用来在不同的测试场景中恢复对象状态,便于调试和测试程序。
-
数据解析:在处理如JSON、XML等数据交换格式时,反序列化是将这些格式的数据解析为程序中的对象或数据结构的过程。
-
安全性:在反序列化过程中,可以实施安全检查,以防止恶意数据导致安全漏洞,如防止反序列化攻击。