unserialize的这个问题是由一个emlog论坛用户在使用时报错而发现的 问题表现情况如下: emlog缓存的保存方式是将php的数据对象(数组)序列化(serialize)后以文件的形式存放,

长度问题:php函数unserialize数据返回false问题分析 unserialize的这个问题是由一个emlog论坛用户在使用时报错而发现的问题表现情况如下:emlog缓存的保存方式是将php的数据对象(数组)序列化(serialize)后以文件的形式存放,读取缓存的时候直接反序列化(unserialize)缓存字符串即可读取数据,关于序列化和反序列化的原理请看我先前的文章《php函数serialize()与unserialize()不完全研究》 阅读详情

unserialize的这个问题是由一个emlog论坛用户在使用时报错而发现的

问题表现情况如下:

emlog缓存的保存方式是将php的数据对象(数组)序列化(serialize)后以文件的形式存放,读取缓存的时候直接反序列化(unserialize)缓存字符串即可读取数据,关于序列化和反序列化的原理请看我先前的文章《php函数serialize()与unserialize()不完全研究》
 

我从用户那里取到的缓存的序列化数据为:

a:1:{s:8:"kl_album";a:4:{s:5:"title";s:12:"精彩瞬 间";s:3:"url";s:41:"http://www.kaisay.cn/?plugin=kl_album";s:8:"is_blank";s:7:"_parent";s:4:"hide";s:1:"n";}}

咋一看了解序列化的人都会说,这个数据很正常啊,没什么问题呢。可是直接把这段字符串进行unserialize,返回的值却是个False;

代码

var_dump(unserialize('a:1:{s:8:"kl_album";a:4:{s:5:"title";s:12:"精彩瞬间";s:3:"url";s:41:"http://www.kaisay.cn/?plugin=kl_album";s:8:"is_blank";s:7:"_parent";s:4:"hide";s:1:"n";}}'));
 

运行结果


 

问题出在哪里呢?答案是 s:41:"http://www.kaisay.cn/?plugin=kl_album"

序列化字符串中标定该字符串http://www.kaisay.cn/?plugin=kl_album的长度是41,可是我们自己数一下却只有37个字符。就是因为这个问题,导致php反序列化字符串失效。

如果将字符串长度改成37,那么程序就会顺利的反序列化

代码:

var_dump(unserialize('a:1:{s:8:"kl_album";a:4:{s:5:"title";s:12:"精彩瞬 间";s:3:"url";s:37:"http://www.kaisay.cn/?plugin=kl_album";s:8:"is_blank";s:7:"_parent";s:4:"hide";s:1:"n";}}'));


通过google后才发现,这个问题国外已经很多的网友遇到了,在官方手册unserialize函数页面的评论中就有很多网友在讨论和研究这个问题的解决方案。

这种情况发生的原因有多种可能,最大的可能就是在序列化数据的时候的编码和反序列化时的编码不一样导致字符串的长度出现偏差。例如数据库编码latin1和UTF-8字符长度是不一样的。

解决方案:

自己用php来纠正序列化字符串中字符串长度的问题,链接

<?php
$unserialized 
= preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $unserialized );
?>

另外一个网友提出一个在非utf-8情况下的BUG,链接

# ascii字符 "\0" 被解析成了 '\0' (\0在C中是字符串的结束符等于chr(0),错误解析后算了2个字符)

// 这么写会出问题
$error = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $unserialized );

// 这么写就没事
$works = preg_replace('!s:(\d+):"(.*?)";!se', '"s:".strlen("$2").":\"$2\";"', $unserialized );

// 根据上面的情况我写出的测试例子(注意代码必须用asc格式保存运行)


$test = 's:7:"hahaha'. chr(0) .'";';
echo preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $test );
echo '<br>';
echo preg_replace('!s:(\d+):"(.*?)";!se', '"s:".strlen("$2").":\"$2\";"', $test );
echo '<br>';
echo unserialize(preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $test ));
echo '<br>';
echo unserialize(preg_replace('!s:(\d+):"(.*?)";!se', '"s:".strlen("$2").":\"$2\";"', $test ));

下图是运行结果:很显然chr(0) 变成了 \0



还有一个情况就是单双引号也会出现长度计算错误的问题:链接

<?php
//--------------------------------------------
// 请看例子的值. 数据从来那里来都没有关系,无论是数据库还是代码中
$heightoptionslist = <<<HEIGHTEND
a:3:{s:37:"Hands/inches (eg. 13&#039; 2&quot;HH)";s:6:"option";s:25:"Inches only (eg.39&quot;)";s:6:"option";s:24:"Centimeters (eg. 153cms)";s:6:"option";}
HEIGHTEND;
//--------------------------------------------
// 将序列化的字符串转换回数组
$heightoptionslist = unserialize($heightoptionslist);
//--------------------------------------------
// 打印值,我们可以很容易看懂
echo "<div><pre>\$heightoptionslist = [\n".print_r($heightoptionslist, true)."\n]</pre></div>";
?>

当字符串中带有没有转换的引号的时候,就会出问题了:

<?php
//--------------------------------------------
// 另外一个例子,
// 这次有没有转换过的引号在里面
$heightoptionslist = <<<HEIGHTEND
a:3:{s:26:"Hands/inches (eg. 13\' 2\"HH)";s:6:"option";s:20:"Inches only (eg.39\")";s:6:"option";s:24:"Centimeters (eg. 153cms)";s:6:"option";}
HEIGHTEND;
//--------------------------------------------
// 
将序列化的字符串转换回数组.
$heightoptionslist = unserialize($heightoptionslist);
//--------------------------------------------
// 返回了一个空的结果.
echo "<div><pre>\$heightoptionslist = [\n".print_r($heightoptionslist, true)."\n]</pre></div>";
?>

以上两端代码运行结果:


 


在字符串还有\r字符的时候计算字符串的长度的时候也会出现问题:链接

When dealing with a string which contain "\r", it seems that the length is not evaluated correctly. The following solves the problem for me :

<?php
// remove the \r caracters from the $unserialized string
$unserialized = str_replace("\r","",$unserialized);

// and then unserialize()
unserialize($unserialized);
?>


总结:解决方案

UTF-8

function mb_unserialize($serial_str) {
    $serial_str= preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $serial_str );
    $serial_str= str_replace("\r", "", $serial_str);      
    return unserialize($serial_str);
}

ASC

function asc_unserialize($serial_str) {

    $serial_str = preg_replace('!s:(\d+):"(.*?)";!se', '"s:".strlen("$2").":\"$2\";"', $serial_str );
    $serial_str= str_replace("\r", "", $serial_str);      
    return unserialize($serial_str);
}

希望本文能给所有遇到该问题的朋友一点帮助

php中unserialize返回false的解决方法 本文实例讲述了php中unserialize返回false的解决方法,分享给大家供大家参考。具体方法如下: php 提供serialize(序列化) 与unserialize(反序列化)方法。 使用serialize序列化后,再使用unserialize反序列化就可以获取原来的数据。 先来看看如下程序实例: <?php $arr = array( 'name' => 'fdipzone', 'gender' => 'male' ); $str = serialize($arr); //序列化 echo 'serialize str:'.$str."\r\n\r\n"; $cont 立即下载

相关推荐

Arch Linux双系统安装避坑指南:从Windows分区到桌面环境全流程

本文提供了一份详尽的Arch Linux与Windows双系统安装避坑指南。内容涵盖从安装前的UEFI环境确认、BitLocker处理、分区规划,到Live环境进入、基础系统安装、GRUB引导配置,再到显卡驱动安装、KDE/GNOME桌面环境部署及中文化设置的全流程。重点解决了双系统安装中的核心痛点,帮助用户在不破坏现有Windows系统的前提下,顺利完成Arch Linux的安装。

nice1的博客 535

php unserialize返回false的解决办法

php unserialize失败返回false原因多半是序列化数据时的编码与反序列化时的编码不一致,导致单引号等特殊字符计算长度不正确,所以解决办法是重新计算长度。百度了很多办法,全是坑呀,百度的那些办法根本没用,都是错的。所以自己写了个,绝对有效!反序列化时用下面函数处理下就行function common_unserialize($serial_str) { $serial...

fangdong88的博客 1225

最新版谷歌浏览器Axure插件(免翻墙)

本文介绍了在Chrome浏览器无法直接打开Axure导出HTML文件的解决方法。由于国内网络限制无法访问Chrome商店,需手动下载安装AxureRP扩展插件(提供百度网盘下载链接)。安装步骤包括:1)启用开发者模式;2)拖拽CRX文件或加载解压文件夹;3)勾选"允许访问文件网址"。同时还提示若浏览器版本过低可能无法正常运行,并给出了浏览器升级方法。该教程详细说明了从插件安装到浏览器升级的完整解决方案。

OldCat先生 2976

php中unserialize 返回false的解决方法

serialize 序列化 unserialize 反序列化 $content = 'a:5:{s:4:"img1";s:5:"35568";s:4:"img2";s:5:"35569";s:4:"img3";s:5:"35570";s:4:"img4";s:5:"35571";s:4:"img5";s:13:"要和商品";}';$content2 = unserialize($content...

weixin_30572613的博客 561

光电振荡器(OEO):从原理到应用,解锁高频微波信号新纪元

本文深入解析了光电振荡器(OEO)的核心原理与前沿应用。OEO通过巧妙的光-电-光转换机制,利用光学谐振腔产生高频、高纯度、低相位噪声的微波信号,有效突破了传统电子电路的频率瓶颈。文章详细拆解了其工作流程,并探讨了在雷达系统、高速光通信及精密测量等领域的硬核应用价值。

weixin_29231027的博客 366

DIY玩家必备:用SSS1623芯片打造高性价比USB麦克风(附完整电路图)

本文详细介绍了如何利用SSS1623芯片DIY高性价比USB麦克风,包括元件选型、电路设计、PCB布局及调试技巧。通过完整的电路参考设计和实用建议,帮助电子爱好者打造专业级录音设备,实现免驱动即插即用功能。

weixin_29166013的博客 239

php unserialize 返回false

出现这种问题的原因: 1、序列化数据时的编码与反序列化时的编码不一致导致,例如数据库是latin1和UTF-8字符长度不一样。 2、单双引号,ascii字符"\0"被解析为 '\0',\0在C中是字符串的结束符等于chr(0),错误解析后算了2个字符。\r在计算长度时也会出问题。 /** * utf8 反序列化 * @param $serial_str * @return mixed */ function mb_unserialize($serial_str) { $serial

凌晨四点的_LA 263

华为云CodeHub代码托管

什么是代码托管 代码托管(CodeHub)是面向软件开发者的基于Git的在线代码托管服务,是具备安全管控、成员/权限管理、分支保护/合并、在线编辑、统计服务等功能的云端代码仓库,旨在解决软件开发者在跨地域协同、多分支并发、代码版本管理、安全性等方面的问题。 代码托管具有以下特性 · 在线代码阅读、修改、提交,随时随地开发,不受地域限制。 · 在线分支管理,包含分支新建、切换、合并,实现多分支并行开发,效率高。 master分支:最为稳定,功能比较完整,随时可发布的代码。 develop分支:用于平时开

LUJINYUANA的博客 1万+

php unserialize bool(false),直击php中unserialize返回false的解决方法_后端开发

本文实例报告了php中unserialize返回false的解决要领,分享给人人供人人参考。具体要领以下:php 供应serialize(序列化) 与unserialize(反序列化)要领。运用serialize序列化后,再运用unserialize反序列化就可以够猎取本来的数据。先来看看以下程序实例:$arr = array('name' => 'fdipzone','gender' =...

weixin_42297349的博客 248

陆地观测卫星数据服务平台深度体验:高分、中巴、资源系列影像的检索与下载技巧

本文深度解析国产陆地观测卫星数据服务平台的使用技巧,重点介绍高分、中巴、资源系列卫星影像的检索与下载方法。通过权限体系解析、高级检索策略、数据预处理等实战技巧,帮助用户高效获取高质量遥感数据,适用于环境监测、资源调查等多种应用场景。

eee77的博客 980

【2026最新版】Open3D(C++)点云处理算法汇总(C++长期更新版)

C++版本Open3D进行点云处理的一些算法使用案例。博客长期更新,最近一次更新时间为:2026年4月11日。

点云侠的博客 1万+

php unserialize 返回false的解决方法

php unserialize 返回false的解决方法

hsyyff的博客 303

大数据开发工程师必备面试题与解答

大数据开发岗位一直是互联网行业的热门方向,面试过程中既考察基础知识,也关注实际项目经验和问题解决能力。本文整理了等核心组件相关的高频面试题及参考解答,帮助大家高效准备面试。大数据面试不仅考察基础理论,更看重项目经验与问题解决能力。本文涵盖了等核心知识点及调优思路,希望能帮助你在面试中游刃有余。

X2829352498的博客 303

PHP反序列化字符逃逸-UNCTF2020

在做UNCTF2020一道WEB题easyunserialize时遇到了,就记录一下 很明显可以看到,我们需要进入_wakeup函数的if判断,并让password等于easy 1._wakeup 这个函数在调用unserialize时会被调用,还有与之类似的_sleep魔术方法,它在使用serialize时被调用。可以看到下面使用unserialize 2.if判断 我们需要更改password的值,但是password是1无法更改。 继续看,filter函数将字符串'challenge.

m0_61666690的博客 404

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

mysql unserialize_serialize与unserialize

相对于网上其他关于Serialize的讲解,不下万篇,学习笔记,稍微总结一番。本篇文章按照浅谈php反序列化漏洞,进行学习指导,基础内容略过。举个栗子先举个例子说明serialize()与unserialize()显而易见,两个函数的例子所表达的形式就是这么简单。再捡个栗子接下来看看下面的例子:1234567891011121314151617181920212223242526header('C...

weixin_34160181的博客 503

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

php unserialize bool(false),php中unserialize返回false的解决方法_PHP教程

php中unserialize返回false的解决方法php 提供serialize(序列化) 与unserialize(反序列化)方法。使用serialize序列化后,再使用unserialize反序列化就可以获取原来的数据。先来看看如下程序实例:12345678910111213$arr = array('name' => 'fdipzone','gender' => 'male...

weixin_36282704的博客 179

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

php unserialize bool(false),php unserialize 返回false的解決方法

php unserialize 返回false的解決方法php 提供serialize(序列化) 與unserialize(反序列化)方法。使用serialize序列化后,再使用unserialize反序列化就可以獲取原來的數據。$arr = array('name' => 'fdipzone','gender' => 'male');$str = serialize($arr); /...

weixin_39608988的博客 147

php的反序列化(unserialize)返回false,本地自己序列化又反序列化却可以。

拿 a:3:{i:10538480057;a:4:{s:9:"stock_num";i:1998;s:6:"sku_id";s:11:"10538480057";s:11:"color_value";s:28:"三层48CM宽黑色(513)";s:10:"size_value";s:12:"默认尺寸";}i:10538480052;a:4:{s:9:"stock_num";i:1087;s:6:"...

wohaoshuai0的博客 471

PHP反序列化unserialize 出现bool false 解决办法

php 提供serialize(序列化) 与unserialize(反序列化)方法。 使用serialize序列化后,再使用unserialize反序列化就可以获取原来的数据。 &lt;?php $arr = array( 'name' =&gt; 'fdipzone', 'gender' =&gt; 'male' ); $str = s...

漫漫程序人生路 676

Php中unserialize()函数返回的是bool(false)

这种情况发生的原因有多种可能,最大的可能就是在序列化数据的时候的编码和反序列化时的编码不一样导致字符串的长度出现偏差。例如数据库编码latin1和UTF-8字符长度是不一样的。 解决方案: 自己从网上找的小函数来纠正序列化字符串中字符串长度的问题 Utf-8 function mb_unserialize($serial_str) {      $serial_str= preg_rep

2298

php unserialize false,PHP: unserialize - Manual

When you serialize an object of a class from a particular namespace, the namespace is recorded as part of the serialization. If you decide to change this namespace's name, it can be hard to read in ol...

weixin_36390615的博客 127
上一篇: java工具集和类库集合
下一篇: php函数unserialize数据返回false问题分析
farcall
博客等级 码龄16年 28粉丝 83原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值