php 提供serialize(序列化) 与unserialize(反序列化)方法。

使用serialize序列化后,再使用unserialize反序列化就可以获取原来的数据。(改表结构或者进行下面操作)

  1. <?php
  2. $arr = array(
  3. 'name' => 'fdipzone',
  4. 'gender' => 'male'
  5. );
  6. $str = serialize($arr); //序列化
  7. echo 'serialize str:'.$str."\r\n\r\n";
  8. $content = unserialize($str); // 反序列化
  9. echo "unserialize str:\r\n";
  10. var_dump($content);
  11. ?>

输出:

  1. serialize str:a:2:{s:4:"name";s:8:"fdipzone";s:6:"gender";s:4:"male";}
  2. unserialize str:
  3. array(2) {
  4. ["name"]=>
  5. string(8) "fdipzone"
  6. ["gender"]=>
  7. string(4) "male"
  8. }

但下面这个例子反序列化会返回false

  1. <?php
  2. $str = 'a:9:
    {s:4:"time";i:1405306402;s:4:"name";s:6:"新
    晨";s:5:"url";s:1:"-";s:4:"word";s:1:"-";s:5:"rpage";s:29:"http://www.baidu.com
    /test.html";s:5:"cpage";s:1:"-";s:2:"ip";s:15:"117.151.180.150";s:7:"ip_city";s:31:"
    中国北京市 北京市移动";s:4:"miao";s:1:"5";}';
  3. var_dump(unserialize($str)); // bool(false)
  4. ?>

检查序列化后的字符串,发现出问题是在两处地方

s:5:"url"

s:29:"http://www.baidu.com/test.html"

这两处应为

s:3:"url"

s:30:"http://www.baidu.com/test.html"

出现这种问题的原因是序列化数据时的编码与反序列化时的编码不一致导致,例如数据库是latin1和UTF-8字符长度不一样。

另外有可能出问题的还有单双引号,ascii字符"\0"被解析为 '\0',\0在C中是字符串的结束符等于chr(0),错误解析后算了2个字符。

\r在计算长度时也会出问题。

解决方法如下:

  1. // utf8
  2. function mb_unserialize($serial_str) {
  3. $serial_str= preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $serial_str );
  4. $serial_str= str_replace("\r", "", $serial_str);
  5. return unserialize($serial_str);
  6. }
  7. // ascii
  8. function asc_unserialize($serial_str) {
  9. $serial_str = preg_replace('!s:(\d+):"(.*?)";!se', '"s:".strlen("$2").":\"$2\";"', $serial_str );
  10. $serial_str= str_replace("\r", "", $serial_str);
  11. return unserialize($serial_str);
  12. }

例子:

  1. echo '<meta http-equiv="content-type" content="text/html; charset=utf-8">';
  2. // utf8
  3. function mb_unserialize($serial_str) {
  4. $serial_str= preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $serial_str );
  5. $serial_str= str_replace("\r", "", $serial_str);
  6. return unserialize($serial_str);
  7. }
  8. $str = 'a:9:
    {s:4:"time";i:1405306402;s:4:"name";s:6:"新
    晨";s:5:"url";s:1:"-";s:4:"word";s:1:"-";s:5:"rpage";s:29:"http://www.baidu.com
    /test.html";s:5:"cpage";s:1:"-";s:2:"ip";s:15:"117.151.180.150";s:7:"ip_city";s:31:"
    中国北京市 北京市移动";s:4:"miao";s:1:"5";}';
  9. var_dump(unserialize($str));    // false
  10. var_dump(mb_unserialize($str)); // 正确

使用处理过单双引号,过滤\r的mb_unserialize方法就能成功反序列化了。

    1. 使用unserialize
    2. bool(false)
    3. 使用mb_unserialize
    4. array(9) {
    5. ["time"]=>
    6. int(1405306402)
    7. ["name"]=>
    8. string(6) "新晨"
    9. ["url"]=>
    10. string(1) "-"
    11. ["word"]=>
    12. string(1) "-"
    13. ["rpage"]=>
    14. string(30) "http://www.baidu.com/test.html"
    15. ["cpage"]=>
    16. string(1) "-"
    17. ["ip"]=>
    18. string(15) "117.151.180.150"
    19. ["ip_city"]=>
    20. string(31) "中国北京市 北京市移动"
    21. ["miao"]=>
    22. string(1) "5"
    23. }

php unserialize 返回false的解决方法的更多相关文章

  1. php中unserialize 返回false的解决方法

    serialize 序列化 unserialize 反序列化 $content = 'a:5:{s:4:"img1";s:5:"35568";s:4:" ...

  2. djongo form.is_valid 返回false的解决方法

    在用djongo编写网站时,有时点击提交按钮之后,并未提交,通过debug会发现是form.is_valid()返回false造成的.但是,具体原因往往并不容易找. 这时在提交的html中添加如下代码 ...

  3. [datatable]关于在DataTable中执行DataTable.Select("条件")返回DataTable的解决方法

    -- :09关于在DataTable中执行DataTable.Select("条件")返回DataTable的解决方法 在实际编程工程中,常常遇到这样的情况:DataTable并不 ...

  4. ajax跨域POST时执行OPTIONS请求服务端返回403forbidden的解决方法

    ajax访问服务端restful api时,由于contentType类型的原因,浏览器会先发送OPTIONS请求. 本人服务端用的是spring mvc框架,web服务器用的是tomcat的,以下给 ...

  5. EasyDarwin返回401 Unauthorized解决方法

    在向EsayDarwin发起 RTSP DESCRIBE请求或者ANNOUNCE推送时,EasyDarwin会返回401 Unauthorized: 原因:在EasyDarwin的RTSP Sessi ...

  6. Type.GetType()在跨程序集反射时返回null的解决方法

    在开发中,经常会遇到这种情况,在程序集A.dll中需要反射程序集B.dll中的类型.如果使用稍有不慎,就会产生运行时错误.例如使用Type.GetType("BNameSpace.Class ...

  7. php中curl返回false的解决办法

    本文介绍一下自己在使用curl中遇到的问题解决办法.希望可以帮助到大家. 原文地址:代码汇个人博客 http://www.codehui.net/info/37.html 首先来看一个封装的curl函 ...

  8. jquery ajax 不执行赋值,return没有返回值的解决方法

    大家先看一段简单的jquery ajax 返回值的js 复制代码 代码如下: function getReturnAjax{ $.ajax({ type:"POST", url:& ...

  9. onsubmit校验表单时利用ajax的return false无效解决方法

    代码: function checkNewEmail(){ var re_email=new RegExp("\\w+@\\w+\\.\\w+\\.?\\w*"); var new ...

随机推荐

  1. [转 ]-- Java线程池使用说明

    Java线程池使用说明 原文地址:http://blog.csdn.net/sd0902/article/details/8395677 一简介 线程的使用在java中占有极其重要的地位,在jdk1. ...

  2. E2 2014.07.01 更新日志

    增加功能   完善功能 电话报修单,添加可以发短信通知客户和技术员选项 商品历程分析,增加按商品分类条件统计 修件库,增加可以按维修商条件过滤,以方便查询某维修商的返修件 维修中,备件转销售时,自动读 ...

  3. iOS - Swift NSDate 时间

    前言 NSDate public class NSDate : NSObject, NSCopying, NSSecureCoding NSDate 用来表示公历的 GMT 时间(格林威治时间).是独 ...

  4. mysql概要(十三)备份和恢复

    1.采用mysql 自带备份命令: 数据库恢复:

  5. Linux 下操作GPIO(两种方法,驱动和mmap)(转载)

    目前我所知道的在Linux下操作GPIO有两种方法: 1.编写驱动,这当然要熟悉Linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据io ...

  6. poj2354Titanic(两点的球面距离)

    链接 球面距离计算公式:d(x1,y1,x2,y2)=r*arccos(sin(x1)*sin(x2)+cos(x1)*cos(x2)*cos(y1-y2)) x1,y1是纬度\经度的弧度单位,r为地 ...

  7. Nginx 启用gzip压缩

    1. 网页压缩 网页压缩是一项由 WEB 服务器和浏览器之间共同遵守的协议,也就是说 WEB 服务器和浏览器都必须支持该技术,所幸的是现在流行的浏览器都是支持的,包括 IE.FireFox.Opera ...

  8. centos JDK安装

    第一步:查看Linux自带的JDK是否已安装 (卸载centOS已安装的1.4) 安装好的CentOS会自带OpenJdk,用命令 java -version ,会有下面的信息: java versi ...

  9. Oct22 实例测试

    实例: http://www.runoob.com/jsp/jsp-form-processing.html http://www.runoob.com/jsp/jsp-writing-filters ...

  10. Eclipse 配置Tomcat

    1.Eclipse EE 配置Tomcat Eclipse EE 主要用于Java Web开发和J2EE项目开发.Eclipse EE中配置Tomcat比较简单,新建一个Tomcat Server即可 ...