当前位置: 首页 > news >正文

在php中的序列化与反序列化

序列化与反序列化的定义:

        序列化是指把对象转化为可传输的字节序列过程,而反序列化是指把字节序列还原为对象的过程。序列化和反序列化是数据持久化和网络传输中常用的技术手段,它们使得数据可以在不同平台、不同系统之间进行有效的存储和通信。

序列化详解:

  1. 概念解释:序列化是将对象的状态信息转换为可以存储或传输的形式(如字节流)的过程。这个过程可以通过不同的方式实现,例如使用Java内置的Serializable接口或者通过其他第三方库如JSON、XML等。

  2. 应用场景:序列化主要用于对象的持久化存储以及网络传输。在存储方面,它可以将对象保存到数据库或文件中;在网络传输方面,它允许对象通过网络发送到远程系统上,然后再反序列化成本地对象。

  3. 实现方法:在Java中,实现序列化的一种常见方法是让对象实现Serializable接口。这个接口虽然没有方法需要实现,但它标记了这个对象可以被JVM序列化和反序列化。

  4. 注意事项:在序列化过程中,静态字段和用transient关键字修饰的字段不会被序列化。此外,为了确保版本兼容性,建议显式定义serialVersionUID来控制版本的一致性。

  5. 性能考虑:选择序列化工具和技术时,需要考虑其性能和生成的数据大小。例如,Protobuf和MessagePack等工具提供了更小的消息大小和更快的序列化速度,适合在大规模分布式系统中使用。

反序列化详解:

  1. 概念解释:反序列化是将字节序列恢复成原有对象形态的过程。这一过程本质上是序列化的逆操作,要求能够准确地还原对象的状态。

  2. 应用场景:当数据从数据库或文件系统中读取出来,或者通过网络接收到序列化的数据后,客户端需要对这些数据进行反序列化,以重建原有的对象状态,进而执行业务逻辑处理。

  3. 实现方法:在Java中,使用ObjectInputStream类可以从输入流中读取字节序列,并将其反序列化为对象。这要求原始对象类实现了Serializable接口。

  4. 安全注意:反序列化过程可能存在安全风险,因为执行反序列化的过程中可能会运行恶意代码。因此,在处理不受信任的输入流时,应当格外小心,并采取相应的安全防护措施。

  5. 兼容性问题:如果序列化对象的类结构发生了变化(如添加了新的字段),可能导致反序列化失败。因此,管理serialVersionUID并合理设计类的结构变化对于保证反序列化的成功率至关重要。

总结而言,序列化与反序列化是数据处理和系统间通信不可或缺的技术。它们支持数据的持久化存储和跨网络传输,适用于多种场合,包括数据缓存、远程方法调用等。在选择具体的序列化技术时,应综合考虑性能、跨平台支持、安全性等因素,以适应不同的应用需求。

序列化与反序列化例子:
 

注意,当我们在序列化一个类的时候我们需要将该类定义出来。如下。

<?php
$raw = 'O:1:"A":1:{s:1:"a";s:1:"b";}';
var_dump(unserialize($raw));  //1进行反序列化并输出
echo serialize(unserialize($raw)); //2先进行反序列化再进行序列化。
?>//输出结果1:
object(__PHP_Incomplete_Class)#1 (2) { ["__PHP_Incomplete_Class_Name"]=> string(1) "A" ["a"]=> string(1) "b" }//输出结果2:
O:1:"A":1:{s:1:"a";s:1:"b";}

这段代码中的$raw字符串是一个序列化后的PHP对象。它包含了一个名为"A"的类的实例,该类有一个属性"a",其值为"b"。我们

$raw解析:

  1. O:1:"A":1:{s:1:"a";s:1:"b";}表示一个对象,其中:
    • O:1:"A"表示对象的类型为"A",并且该类型的类定义在当前命名空间中(即没有指定命名空间)。
    • 1表示对象的属性数量为1个。
    • {s:1:"a";s:1:"b";}表示对象的属性列表,其中:
      • s:1:"a"表示一个字符串类型的属性,属性名为"a",长度为1。
      • s:1:"b"表示另一个字符串类型的属性,属性名为"a"的值,长度为1。
  2. 反序列化$raw字符串后,会得到一个名为"A"的类的实例,该实例有一个属性"a",其值为"b"。

|我们通过对php的代码分析发现我们序列化了一个不存在的类“A“,但是当我们对$raw进行反序列化再序列化之后的输出和原来一样,这是为什么呢?
原因如下:

        可以发现PHP在遇到不存在的类时,会把不存在的类转换成__PHP_Incomplete_Class这种特殊的类,同时将原始的类名A存放在__PHP_Incomplete_Class_Name这个属性中,其余属性存放方式不变。而我们在序列化这个对象的时候,serialize遇到__PHP_Incomplete_Class这个特殊类会倒推回来,序列化成__PHP_Incomplete_Class_Name值为类名的类,我们看到的序列化结果不是O:22:"__PHP_Incomplete_Class_Name":2:{xxx}而是O:1:"A":1:{s:1:"a";s:1:"b";}

正常情况下的代码应该这样写:

<?php
class A {public $a;
}  //将A这个类定义出来$raw = 'O:1:"A":1:{s:1:"a";s:1:"b";}';
$object = unserialize($raw);
var_dump($object);  //输出反序列化的结果
?>
//输出结果如下:
object(A)#1 (1) {["a"]=>string(1) "b"
}

这表示我们成功地定义了类 "A",并通过反序列化得到了一个该类的实例,其中属性 $a 的值被正确设置为 "b"。

注意:

在实际应用中,序列化和反序列化数据时,确保在进行反序列化之前,相关的类已经被定义,以避免遇到__PHP_Incomplete_Class或其它潜在问题。

相关文章:

  • 【elementui源码解析】如何实现自动渲染md文档-第三篇
  • 【服务器04】之【Navicat连接阿里云】
  • 上网行为管理系统是干什么的?4款高人气上网管理软件盘点
  • Python联动Mysql
  • RisingWave 1.9 发布!新增 Snowflake sink 连接器
  • 【安全函数】常用的安全函数的使用
  • WPF学习(2)--类与类的继承2-在窗口的实现
  • opencv 打开图片后,cv::mat存入共享内存的代码,如何设置队列?
  • C 语言通用MySQL 功能增删查改功能.
  • [Mysql] 的基础知识和sql 语句.教你速成(上)——逻辑清晰,涵盖完整
  • SwaggerSpy:一款针对SwaggerHub的自动化OSINT安全工具
  • NetSuite Inventory Transfer Export Saved Search
  • 安装TensorFlow2.12.0
  • Electron+Vue开源软件:洛雪音乐助手V2.8畅享海量免费歌曲
  • 【Python】从0开始的Django基础
  • python3.6+scrapy+mysql 爬虫实战
  • [ JavaScript ] 数据结构与算法 —— 链表
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • Android组件 - 收藏集 - 掘金
  • echarts的各种常用效果展示
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • Python学习之路16-使用API
  • Theano - 导数
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 缓存与缓冲
  • 坑!为什么View.startAnimation不起作用?
  • 什么是Javascript函数节流?
  • 文本多行溢出显示...之最后一行不到行尾的解决
  • 小程序滚动组件,左边导航栏与右边内容联动效果实现
  • No resource identifier found for attribute,RxJava之zip操作符
  • 《码出高效》学习笔记与书中错误记录
  • Java性能优化之JVM GC(垃圾回收机制)
  • ​VRRP 虚拟路由冗余协议(华为)
  • #if和#ifdef区别
  • #laravel 通过手动安装依赖PHPExcel#
  • #职场发展#其他
  • ( 10 )MySQL中的外键
  • ()、[]、{}、(())、[[]]命令替换
  • (1)Hilt的基本概念和使用
  • (12)目标检测_SSD基于pytorch搭建代码
  • (4.10~4.16)
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (C语言)输入一个序列,判断是否为奇偶交叉数
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (定时器/计数器)中断系统(详解与使用)
  • (附源码)c#+winform实现远程开机(广域网可用)
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (含笔试题)深度解析数据在内存中的存储
  • .md即markdown文件的基本常用编写语法
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .Net Core 中间件与过滤器
  • .Net mvc总结
  • @Bean, @Component, @Configuration简析
  • @cacheable 是否缓存成功_Spring Cache缓存注解