千家信息网

PHP序列化和反序列化语法的差异

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,本篇内容介绍了"PHP序列化和反序列化语法的差异"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!介绍官
千家信息网最后更新 2026年10月31日PHP序列化和反序列化语法的差异

本篇内容介绍了"PHP序列化和反序列化语法的差异"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

介绍

官方文档中介绍PHP序列化和反序列化如下:

所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。unserialize()函数能够重新把字符串变回php原来的值。 序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。 为了能够unserialize()一个对象,这个对象的类必须已经定义过。如果序列化类A的一个对象,将会返回一个跟类A相关,而且包含了对象所有变量值的字符串。

简单说序列化是对象转化字符串的过程,反序列化是字符串还原对象的过程。

环境

文章中所述内容使用环境如下:

PHP7.3.1、SDKVSCodeC++和C

环境配置建议参考:《WINDOWS下用VSCODE调试PHP7源代码》https://www.jianshu.com/p/29bc0443***6(作者经过几小时尝试后找到最全的版本)

在网上公开参数反序列化执行流程已经非常详细,但是对于一些细节地方有一些不足,其中就包括序列化和反序列化之间的语法差异问题

差异问题

序列化

我们通过编译PHP内核源码分析,发现PHP序列化在默认情况下在对象转换中加入:{和}用来拼接成字符串。

[var.c]Line:882static void php_var_serialize_intern()Line:896if (ce->serialize(struc, &serialized_data, &serialized_length, (zend_serialize_data *)var_hash) == SUCCESS) {                        smart_str_appendl(buf, "C:", 2);                        smart_str_append_unsigned(buf, ZSTR_LEN(Z_OBJCE_P(struc)->name));                        smart_str_appendl(buf, ":\"", 2);                        smart_str_append(buf, Z_OBJCE_P(struc)->name);                        smart_str_appendl(buf, "\":", 2);                        smart_str_append_unsigned(buf, serialized_length);                        smart_str_appendl(buf, ":{", 2);                        smart_str_appendl(buf, (char *) serialized_data, serialized_length);                        smart_str_appendc(buf, '}');                    }Line:952smart_str_appendl(buf, ":{", 2);Line:995smart_str_appendc(buf, '}');

咱们来看上面这段代码,PHP会使用smart_str_appendl为序列化字符串前后拼接:{和},从var.c的第882行开始进入序列化逻辑。在第896行进行序列化字符串拼接,第952行和第995行,对于内嵌方法进行拼接。

反序列化

反序列化是将序列化的字符串,按照一定语法规则进行转化还原。

[var_unserialize.c]Line:655static int php_var_unserialize_internal()Line:674{    YYCTYPE yych;    static const unsigned char yybm[] = {          0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,         128, 128, 128, 128, 128, 128, 128, 128,         128, 128,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,           0,   0,   0,   0,   0,   0,   0,   0,     };    if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);    yych = *YYCURSOR;    switch (yych) {    case 'C':    case 'O':    goto yy4;    case 'N':    goto yy5;    case 'R':    goto yy6;    case 'S':    goto yy7;    case 'a':    goto yy8;    case 'b':    goto yy9;    case 'd':    goto yy10;    case 'i':    goto yy11;    case 'o':    goto yy12;    case 'r':    goto yy13;    case 's':    goto yy14;    case '}':    goto yy15;    default:    goto yy2;    }Line:776yy15:    ++YYCURSOR;    {    /* this is the case where we have less data than planned */    php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data");    return 0; /* not sure if it should be 0 or 1 here? */}

通过内核代码能够看到第655行进入反序列化,反序列化是利用词法扫描,判断各项符号转换对应对象。能够看到反序列化中对于}进行了处理,处理中只是对计数器加一并没有其他操作。

实际作用

反序列化语法的差异,对于安全防护设备判断反序列化产生很大的影响。在Snort中,有段规则如下:

alert tcp any any -> any [80,8080,443] (uricontent:".php"; pcre:"/\{\w:.+?\}/"; sid:1; msg:php_serialize;)

在攻击载荷中可以使用大多数字符代替{},从而导致规则失效。

"PHP序列化和反序列化语法的差异"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

序列 对象 字符 字符串 差异 语法 内容 环境 规则 过程 代码 内核 函数 实际 情况 文章 方法 更多 知识 问题 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网高科技 互联网 科技 互联网未来科技 善班互联网科技有限公司 互联网科技网站 互联网科技项目计划书材料类 华夏恒生互联网科技013171 华夏恒生科技与互联网科技 佛山市拉法互联网科技有限公司 上海科技产业互联网平台 广东工业互联网大赛深圳学泰科技 产业互联网科技服务公司 互联网相关科技技术 抖集互联网科技技术咨询 珠海东科互联网科技有限公司 互联网时代科技型公司的机会 互联网公司属于科技吗 上海万顺科技互联网有限公司招聘 互联网的科技体现在哪里 黑龙江互联网科技公司 互联网科技的英文 成都互联网科技公司 科技互联网公司logo 上游互联网科技 湖南洣水互联网科技有限公司扣款 华夏恒生科技与互联网科技 滨湖区互联网智能科技产品有哪些 广州富喜互联网络科技 九思连强互联网电子科技有限公司 互联网时代科技型公司的机会
0