php

浏览 159 扫码 分享 2023-11-25 03:51:40

                [序列化介绍](#d9tav2)[方便存储如何理解呢?](#6gbfr3)[方便传输如何理解呢?](#vvf9u)[数据的序列化的类别](#e87gkw)[文本序列化](#9e80mm)[二进制序列化](#1157bu)[序列化技术指标](#7f0w6x)[一、PHP 序列化变量的 4 种方法](#ggp3l9)[1. serialize 和 unserialize 函数](#ntgcs)[2. json_encode 和 json_decode](#8x1f1r)[3. var_export 和 eval](#f5nags)[4. wddx_serialize_value 和 wddx deserialize](#ar2weg)[结论](#5ixzy6)[PHP序列化对比](#b8nd8u)[PHP 内置的 serialize](#9bsu0l)[PHP 内置的 JSON 解析器、](#9aeni9)[PHP 扩展 JSOND](#g44u6c)[PHP 扩展 msgpack。](#6um2ic)[测试代码如下:](#fffo1v)[总结一下:](#8iy3sk)

本文由 简悦 SimpRead 转码, 原文地址 cloud.tencent.com

序列化介绍

序列化是将变量转换为可保存或传输的字符串的过程;反序列化就是在适当的时候把这个字符串再转化成原来的变量使用。

其实将数据序列化的作用无外乎有两个:

方便传输方便存储

方便存储如何理解呢?

如:存储对象或者数组到数据库比如我们有个 PHP 对象或者一个 PHP 数组需要存储到数据库甚至文件中,这显然是不可能的,这个时候必须要将 PHP 对象或者 PHP 数组序列化后再执行存储操作。将对象直接存储起来,用的时候只需要简单的反序列化后就可以投产使用了,避免了 new 一次带来的性能耗费。

方便传输如何理解呢?

其实序列化在传输中应用的相对更多更常见些许。最简单的一个例子,一个码前端的码了一个 ajax 找你给 TA 提供一个 API,那么这个时候你俩得商量返回什么数据,比如 json 或者 xml,甚至你俩自己作死约定私有数据格式。比如在一个比较典型的服务架构中,网关服务器和内部 RPC 服务器之间通过 msgpack 或者 protobuf传递数据。这都是典型的序列化为了传输的典型应用案例。

这里序列化的概念可能更为广泛和笼统一些,包括传统的 serialize、json、msgpack、protobuf 等。

数据的序列化的类别

文本序列化

更好的可读性

常见如 json、serialize、xml 等

二进制序列化

序列化的速度快,序列化后数据小

常见如 msgpack、protobuf、thrift 等

序列化技术指标

一般说来,考验序列化技术的性能指标一共有两个,一个是序列化的速度,一个是序列化后数据的大小,自然是序列化速度越快、序列化后的数据越小为佳。

就目前来看,protobuf、msgpack 等二进制序列化无论是速度上还是数据大小上,都要比文本序列化更好。不过话说回来,文本序列化有更好的可读性

一、PHP 序列化变量的 4 种方法

1. serialize 和 unserialize 函数

这两个是序列化和反序列化 PHP 中数据的常用函数。

<?php$a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut');//序列化数组$s = serialize($a);echo $s;//输出结果:a:3:{s:1:"a";s:5:"Apple";s:1:"b";s:6:"banana";s:1:"c";s:7:"Coconut";}echo '<br /><br />';//反序列化$o = unserialize($s);print_r($o); 当数组值包含如双引号、单引号或冒号等字符时,它们被反序列化后,可能会出现问题。为了克服这个问题,一个巧妙的技巧是使用 base64_encode 和 base64_decode。

$obj = array(); //序列化 $s = base64_encode(serialize($obj)); //反序列化 $original = unserialize(base64_decode($s));

但是 base64 编码将增加字符串的长度。为了克服这个问题,可以和 gzcompress 一起使用。

//定义一个用来序列化对象的函数

function my_serialize( $obj ) { return base64_encode(gzcompress(serialize($obj))); }

//反序列化 function my_unserialize($txt) { return unserialize(gzuncompress(base64_decode($txt))); }

2. json_encode 和 json_decode

使用 JSON 格式序列化和反序列化是一个不错的选择:

json_encode 序列化对象会失败JSON 格式是可读的。JSON 格式比 serialize 返回数据结果小。JSON 格式是开放的、可移植的。其他语言也可以使用它。 $a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut');

//序列化数组 $s = json_encode($a); echo $s; //输出结果:{"a":"Apple","b":"banana","c":"Coconut"}

echo '<br /><br />';

//反序列化 $o = json_decode($s);

在上面的例子中,json_encode 输出长度比上个例子中 serialize 输出长度显然要短。

3. var_export 和 eval

var_export 函数把变量作为一个字符串输出;eval 把字符串当成 PHP 代码来执行,反序列化得到最初变量的内容。

$a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut');

//序列化数组 $s = var_export($a , true); echo $s; //输出结果: array ( 'a' => 'Apple', 'b' => 'banana', 'c' => 'Coconut', )

echo '<br /><br />';

//反序列化 eval('$my_var=' . $s . ';');

print_r($my_var);

4. wddx_serialize_value 和 wddx deserialize

wddx_serialize_value 函数可以序列化数组变量,并以 XML 字符串形式输出。

$a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut');

//序列化数组 $s = wddx_serialize_value($a); echo $s;

//输出结果(查看输出字符串的源码):<wddxPacket version='1.0'><header/><data><struct><var name='a'><string>Apple</string></var><var name='b'><string>banana</string></var><var name='c'><string>Coconut</string></var></struct></data></wddxPacket>

echo '<br /><br />';

//反序列化 $o = wddx_deserialize($s);

print_r($o); //输出结果:Array ( [a] => Apple [b] => banana 1 => Coconut )

可以看出,XML 标签字符较多,导致这种格式的序列化还是占了很多空间。

结论

上述所有的函数在序列化数组变量时都能正常执行,但运用到对象就不同了。例如 json_encode 序列化对象就会失败。反序列化对象时,unserialize 和 eval 将有不同的效果。

英文原文:3 ways to serialize variables in php

PHP序列化对比

今天带到这里的这里的有四个具体的方案,这四种方案都是简单粗暴、开箱即用类型的,我们分别测试感受下,看哪个更适合我们。

其中前三个都是文本类型的,msgpack 则是二进制类型的。

PHP 内置的 serialize

serialize 用法 serialize(),序列化方法。 unserialize(),反序列化方法。

PHP 内置的 JSON 解析器、

json 用法 json_encode() 编码 json_decode() 解码

PHP 扩展 JSOND

JSOND 作为 PHP 内置的 JSON 解析器的高级版本,坊间一直传闻速度上要比内置的更牛 X 一些,作为扩展,这货需要额外安装,附送地址:https://pecl.php.net/get/jsond-1.4.0.tgz

jsond_encode(),和json_encode()一样,后面多个字母d而已。jsond_decode(),和json_decode()一样,后面多个字母d而已。

PHP 扩展 msgpack。

msgpack 是一个鸟哥等人搞的一套二进制序列化工具,slogan 就是 “It’s like JSON.but fast and small.”,附送地址:https://pecl.php.net/get/msgpack-2.0.2.tgz

msgpack_pack(),序列化方法。msgpack_unpack(),反序列化方法。

测试代码如下:

<?php // 故意搞了一个还算大的php数组,更容易看出差距来 $arr = array( array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), 'relation' => array( array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), ), ) );

// 每种序列化方案都执行100000次 $counter = 100000;

// json序列化方案,执行100000次 echo PHP_EOL.PHP_EOL; $start = microtime( true ); for( $i = 1; $i <= $counter; $i++ ){ $json = json_encode( $arr ); } $size = strlen( $json ); $end = microtime( true ); $cost_time = $end - $start; echo "json_encode : 耗费时间为{$cost_time} , 数据体积为{$size}".PHP_EOL;

// jsond序列化方案,执行100000次 $start = microtime( true ); for( $i = 1; $i <= $counter; $i++ ){ $jsond = jsond_encode( $arr ); } $size = strlen( $jsond ); $end = microtime( true ); $cost_time = $end - $start; echo "jsond_encode : 耗费时间为{$cost_time} , 数据体积为{$size}".PHP_EOL;

// serialize序列化方案,执行100000次 $start = microtime( true ); for( $i = 1; $i <= $counter; $i++ ){ $serialize = serialize( $arr ); } $size = strlen( $serialize ); $end = microtime( true ); $cost_time = $end - $start; echo "serialize : 耗费时间为{$cost_time} , 数据体积为{$size}".PHP_EOL;

// msgpack序列化方案,执行100000次 $start = microtime( true ); for( $i = 1; $i <= $counter; $i++ ){ $msgpack = msgpack_pack( $arr ); } $size = strlen( $msgpack ); $end = microtime( true ); $cost_time = $end - $start; echo "msgpack耗费时间为 : {$cost_time} , 数据体积为{$size}".PHP_EOL; echo PHP_EOL.PHP_EOL;

将文件保存为 test.php,然后 php test.php 执行,结果如下图所示:

image.png

总结一下:

jsond 确实是要比 json 快一些的,数据体积一样测试发现,serialize比json快,但是serialize() 数据体积确实大(因为还保留了数据类型说明)msgpack 最佳

                        ![](/static/images/thumbs.png)

                    若有收获,就点个赞吧

                    0 人点赞









                        下一篇:[](#)




                        [](/)

                            [](javascript:)


                            [](javascript:)


                            [](/record/8263)



                                ![书签](/static/images/icon-bookmark-list.png)




                             ![添加书签](/static/images/icon-bookmark-add.png)
                             ![移除书签](/static/images/icon-bookmark-remove.png)



                            [](javascript:void(0);)


                            [](#)


                            [](javascript:;)






















                [PHP](/read/rendacode@zvi88r/E8m6KsLvPrfcKyL0)[总结](/read/rendacode@zvi88r/mXiNrrQB-vY3xJNb)[项目总结](/read/rendacode@zvi88r/owm3gs)[实用函数总结](/read/rendacode@zvi88r/wiypcz)[数组操作](/read/rendacode@zvi88r/ds1t52)[总结](/read/rendacode@zvi88r/imdxn6)[Session总结](/read/rendacode@zvi88r/anmzg4)[=&amp;引用赋值  ,=值赋值,  写时拷贝](/read/rendacode@zvi88r/tifgnm)[PHP的闭包,匿名函数](/read/rendacode@zvi88r/ocab1k)[PHP的变量作用域和全局变量](/read/rendacode@zvi88r/agbcm3)[1 上 PHP基础知识](/read/rendacode@zvi88r/qi90ie)[1 下 PHP基础知识考察点](/read/rendacode@zvi88r/kn14aq)[2 JavaScript](/read/rendacode@zvi88r/vc6dgb)[5 程序设计](/read/rendacode@zvi88r/ssvbfl)[6 PHP框架](/read/rendacode@zvi88r/gctbgf)[php](/read/rendacode@zvi88r/-jrwkHeapar88EJg)[php7](/read/rendacode@zvi88r/zcmsuf)[重复提交](/read/rendacode@zvi88r/hxxwg7)[不重复订单号](/read/rendacode@zvi88r/gdr8ea)[PHP弱类型变量是如何实现的](/read/rendacode@zvi88r/tk9mcr)[RESTful API 设计指南](/read/rendacode@zvi88r/zomn2a)[PHP读取大文件](/read/rendacode@zvi88r/ynn243)[PHP读取XML大文件 数据导入](/read/rendacode@zvi88r/fsa1gr)[php高级IO用法](/read/rendacode@zvi88r/mbb5iu)[PHP 发送 HTTP 请求](/read/rendacode@zvi88r/to7q5b)[PHP序列化的四种实现方法与横向对比](/read/rendacode@zvi88r/hqnsut)[命名空间 namespace  use区别   __autoload](/read/rendacode@zvi88r/drsd50)[PHP生成器](/read/rendacode@zvi88r/pa8k9s)[加密图片,图片权限](/read/rendacode@zvi88r/csot6p)[在PHP中使用协程实现多任务调度](/read/rendacode@zvi88r/munodc)[PHP多线程开发的配置](/read/rendacode@zvi88r/ttbg0h)[远程获取文件php](/read/rendacode@zvi88r/gex497)[PHP写日志fwrite和file_put_contents的区别与性能](/read/rendacode@zvi88r/pxnr4p)[PHP实现执行定时任务的几种思路详解](/read/rendacode@zvi88r/rfwnoh)[PHP 实现定时器任务(Timer)](/read/rendacode@zvi88r/utz458)[PHP 超时和内存](/read/rendacode@zvi88r/aoys1q)[php ob系列函数总结](/read/rendacode@zvi88r/hkde0u)[二维码](/read/rendacode@zvi88r/gqeeh4)[短网址](/read/rendacode@zvi88r/pigq7u)[ImageMagick生成base64图片](/read/rendacode@zvi88r/rue8bt)[PHP图片上传程序](/read/rendacode@zvi88r/cye1gf)[php生成桌面快捷方式](/read/rendacode@zvi88r/myacxm)[PHP 中的错误和异常](/read/rendacode@zvi88r/zhwhfu)[php.ini 文件配置详解](/read/rendacode@zvi88r/wv2ynk)[重定向.htaccess](/read/rendacode@zvi88r/kkrsue)[laravel](/read/rendacode@zvi88r/W3r9dqfH6srKxLIA)[laravel异常提示界面](/read/rendacode@zvi88r/pv5i2v)[laravel笔记](/read/rendacode@zvi88r/ezsshp)[laravel中trait用法](/read/rendacode@zvi88r/mtn0yv)[maatwebsite/excel](/read/rendacode@zvi88r/mizeo1)[having 分页](/read/rendacode@zvi88r/nsyhmo)[分页带连接](/read/rendacode@zvi88r/pgi8zy)[吃透 Laravel 的 Ioc 容器](/read/rendacode@zvi88r/zoue55)[软删除](/read/rendacode@zvi88r/czikm8)[laravel邮件](/read/rendacode@zvi88r/ir3357)[Laravel调试工具Debugbar](/read/rendacode@zvi88r/hyg8p4)[Laravel的验证码库gregwar_captcha - 简书](/read/rendacode@zvi88r/zh5nax)[laravel部署服务器,优化,安全等问题](/read/rendacode@zvi88r/dv4nwu)[laravel5.4 使用](/read/rendacode@zvi88r/luqmgn)[laravel5.1Auth验证替换成md5](/read/rendacode@zvi88r/iulqg1)[laravel SQL写法](/read/rendacode@zvi88r/nsgli0)[laravel cursor 游标](/read/rendacode@zvi88r/ug9x5t)[laravel 源码解析](/read/rendacode@zvi88r/nfo18f)[laravel 验证 unique用法](/read/rendacode@zvi88r/bwer34)[laravel 可写权限](/read/rendacode@zvi88r/tukmz7)[Laravel 开发 API](/read/rendacode@zvi88r/mpkdn4)[Laravel 5.1 更改默认登录跳转路径](/read/rendacode@zvi88r/xzn1u5)[Laravel 5.1 改为中文语言](/read/rendacode@zvi88r/obikc9)[Laravel 5 程序优化技巧 - 简书](/read/rendacode@zvi88r/pt6538)[laravel  学院君](/read/rendacode@zvi88r/ziopeh)[Envoyer](/read/rendacode@zvi88r/gixl8t)[chunk,分块处理数据](/read/rendacode@zvi88r/kwg0q7)[在Laravel项目中实现Ajax上传用户头像](/read/rendacode@zvi88r/ufm1sm)[使用 Laravel Notifynder 扩展轻松实现 Laravel 应用的消息通知功能 – Laravel学院](/read/rendacode@zvi88r/ldlx5v)[上传图片](/read/rendacode@zvi88r/nh5aor)[任务调度](/read/rendacode@zvi88r/hwdm2z)[简单的服务容器例子](/read/rendacode@zvi88r/wmt200)[查询构建起DB和ORM选择问题](/read/rendacode@zvi88r/xf0ahu)[使用中间件禁用浏览器缓存](/read/rendacode@zvi88r/mctf9c)[Yaf](/read/rendacode@zvi88r/fVhHUjzcmbTRpW8S)[yaf笔记](/read/rendacode@zvi88r/ufbv61)[swoole](/read/rendacode@zvi88r/Sn8pPf0aOKGGj9dy)[1 server跟client](/read/rendacode@zvi88r/vx17i8)[1 swoole部署及快速入门](/read/rendacode@zvi88r/irb0gq)[爬虫](/read/rendacode@zvi88r/gwJZFVrM1CCXJdzo)[PHP爬虫框架](/read/rendacode@zvi88r/ym9y05)[内核](/read/rendacode@zvi88r/a9YRLyXvoypOYS-I)[PHP7 中全新的 zval 容器和引用计数机制](/read/rendacode@zvi88r/auwx10)[php7 垃圾回收机制](/read/rendacode@zvi88r/swx86d)[PHP 7 数组的实现](/read/rendacode@zvi88r/znznft)[CGI、FastCGI、PHP-FPM](/read/rendacode@zvi88r/lsv56g)[opcache和JIT](/read/rendacode@zvi88r/kof2dw)[从php到浏览器的缓存机制](/read/rendacode@zvi88r/pwgw10)[PHP 进程信号处理](/read/rendacode@zvi88r/btmga3)[文章列表](/read/rendacode@zvi88r/uozp1f)[Go](/read/rendacode@zvi88r/AXl6WlHt4Jit_-Za)[Golang 调度器 GMP 原理与调度全分析](/read/rendacode@zvi88r/gib8tm)[GMP模型](/read/rendacode@zvi88r/wldg72)[channel的实现原理](/read/rendacode@zvi88r/dgo6o9)[总结](/read/rendacode@zvi88r/gf66c0)[go基础](/read/rendacode@zvi88r/cd9gs0)[MixGo XFMT 解决 Golang 结构体嵌套格式化打印指针地址](/read/rendacode@zvi88r/hq3pe0)[Go 资料](/read/rendacode@zvi88r/sxugmm)[go语言从入门到实战](/read/rendacode@zvi88r/mwqacg)[Java](/read/rendacode@zvi88r/fp_2wTgAr6QI1ULg)[你知道java类是怎么跑起来的吗](/read/rendacode@zvi88r/bwa1fi)[我是一个线程池](/read/rendacode@zvi88r/qbpmca)[Java中的21种锁](/read/rendacode@zvi88r/akg5sy)[如何避免死锁,我们有套路可循](/read/rendacode@zvi88r/he3crg)[面试问我,创建多少个线程合适?我该怎么说](/read/rendacode@zvi88r/lktv4i)[JAVA线上故障排查全套路](/read/rendacode@zvi88r/gymlp4)[Java学习笔记](/read/rendacode@zvi88r/xwrggt)[Java项目部署到Windows服务器](/read/rendacode@zvi88r/wxrgvk)[Python](/read/rendacode@zvi88r/8ohqgdei2SvC0aIA)[Python3笔记](/read/rendacode@zvi88r/uprtsu)[Python 爬虫分析](/read/rendacode@zvi88r/cuz7in)[图解|为什么 Python 多线程无法利用多核](/read/rendacode@zvi88r/glaos0)[微信](/read/rendacode@zvi88r/EJ6Vm4qQ0XqtJuVl)[公众号](/read/rendacode@zvi88r/lgnLQEiwJl-byoC8)[微信支付笔记](/read/rendacode@zvi88r/cehtpa)[微信支付服务器CA证书更换服务器安装der证书的方法 DigiCert的根证书](/read/rendacode@zvi88r/tf80c3)[h5获取地理位置](/read/rendacode@zvi88r/pthniq)[微信商户后台营销活动](/read/rendacode@zvi88r/ptrtg5)[微信公众平台开发-在线书](/read/rendacode@zvi88r/gy5ckf)[微信公众号开发问题](/read/rendacode@zvi88r/oz5oca)[商家收款码](/read/rendacode@zvi88r/im2gp7)[小程序](/read/rendacode@zvi88r/50q-0PBFxnGJYmg5)[小程序云开发优缺点及适用场景](/read/rendacode@zvi88r/vkrvz6)[通用](/read/rendacode@zvi88r/QGgrxSxESg3IQ9VD)[通信接口标准](/read/rendacode@zvi88r/ip2acb)[超时订单自动关闭](/read/rendacode@zvi88r/ze8wpf)[一文搞懂Cookie、Session、Token、JWT?](/read/rendacode@zvi88r/xr4ugb)[JSON Web Token](/read/rendacode@zvi88r/nfwhrh)[API 接口签名验证](/read/rendacode@zvi88r/stc37v)[第三方登录OAuth2.0协议](/read/rendacode@zvi88r/ygai35)[过滤不可见字符](/read/rendacode@zvi88r/xzop2z)[下载文件/在线预览PDF](/read/rendacode@zvi88r/tszrg7)[Restful 与 WebService 的区别](/read/rendacode@zvi88r/hbdd35)[30 个提升团队研发效能的锦囊](/read/rendacode@zvi88r/mdav22)[大厂是如何设计接口的?](/read/rendacode@zvi88r/ey1pkn)[后端语言性能](/read/rendacode@zvi88r/gdfnos)[后端程序员都做些什么?](/read/rendacode@zvi88r/am43uw)[42图揭秘,「后端技术学些啥」](/read/rendacode@zvi88r/to4ybv)[当我们在谈论高并发的时候究竟在谈什么? - 个人文章 - SegmentFault 思否](/read/rendacode@zvi88r/8a402826-c440-4141-bf6f-35b1fb7b3f74)[一元云购算法(暗箱操作)](/read/rendacode@zvi88r/akgeob)




                    暂无相关搜索结果!







                    让时间为你证明

            手机扫一扫,轻松掌上读








                    请下载您需要的格式的文档,随时随地,享受汲取知识的乐趣!
                    [PDF文档](/export/rendacode@zvi88r?output=pdf)
                    [EPUB文档](/export/rendacode@zvi88r?output=epub)
                    [MOBI文档](/export/rendacode@zvi88r?output=mobi)


















                阅读进度:  0.00% ( 0/0 )
                [重置阅读进度](#)

正文图片