当前位置:首页 > PHP教程 > php数组 > 列表

PHP serialize 怎么把数组转成字符串

发布:smiling 来源: PHP粉丝网  添加日期:2026-09-12 11:20:16 浏览: 评论:0 

serialize() 将数组转为 PHP 特有二进制安全字符串格式(如 a:2:{i:0;s:5:"hello";i:1;i:123;}),仅能被 unserialize() 还原,不适用于 JSON 传输或跨语言场景,且不支持资源、闭包,对用户输入反序列化存在安全风险。

serialize() 能直接把数组转成字符串,但结果不是人能读的

PHP 的 serialize() 函数确实能把数组(包括多维、含对象、含资源引用的数组)转成字符串,但它生成的是 PHP 特有的二进制安全序列化格式,比如 a:2:{i:0;s:5:"hello";i:1;i:123;}。这种字符串只能被 PHP 的 unserialize() 安全还原,不能当 JSON 用,也不能直接存进某些数据库字段(比如 MySQL 的 TEXT 类型虽能存,但后续查出来没法被其他语言解析)。

只适合 PHP 内部存储或缓存场景(如 Redis 的 string 值、Session 数据、文件缓存)

如果数组里有匿名函数、资源(resource)、闭包或某些扩展对象,serialize() 会失败或产生不可预测行为

PHP 8.1+ 对未声明类型的对象序列化会触发 E_WARNING,注意错误报告级别

常见错误:用 serialize() 当 JSON 用,然后前端解析失败

典型现象是:PHP 里 echo serialize($arr) 输出一串乱码似的字符,前端 JS 调 JSON.parse() 直接报错 Unexpected token a in JSON at position 0——因为开头那个 a: 是 serialize() 的类型标识,不是 JSON。

要给前端传数据,必须用 json_encode(),不是 serialize()

json_encode() 不支持资源、资源句柄、循环引用;serialize() 支持循环引用但不支持资源

中文在 json_encode() 里默认是 Unicode 转义(\u4f60\u597d),加 JSON_UNESCAPED_UNICODE 参数可避免

简单示例:对比 serialize 和 json_encode 的输出

  1. $arr = ['name' => '张三''scores' => [85, 92]]; 
  2. echo serialize($arr);     // a:2:{s:4:"name";s:6:"张三";s:6:"scores";a:2:{i:0;i:85;i:1;i:92;}} 
  3. echo json_encode($arr);  // {"name":"张三","scores":[85,92]} 

注意:serialize() 中文长度按字节算(UTF-8 下“张三”是 6 字节),所以字符串里出现 s:6:"张三";而 json_encode() 默认输出 UTF-8 原始字节(加了 JSON_UNESCAPED_UNICODE 才会这样)。

反序列化时最常踩的坑:忘记校验来源和类型

unserialize() 是高危函数,如果对用户可控输入(比如 cookie、GET 参数、数据库读出的字段)直接调用,可能触发反序列化漏洞(RCE 或任意类方法调用)。PHP 7.4+ 引入了 unserialize($str, ['allowed_classes' => false]) 来禁用对象反序列化,强烈建议显式设置。

永远不要 unserialize($_GET['data']) 这样写

如果只是存数组,且确定没有对象,用 allowed_classes => [](空数组)更安全

Redis 缓存里用 serialize() 没问题,但取出后务必检查是否为 FALSE(反序列化失败返回 FALSE,不是异常)

实际用的时候,别只盯着“能不能转”,先想清楚:这串字符串最后谁来读?要不要跨语言?有没有用户输入参与?这几个问题的答案,基本就决定了该用 serialize()、json_encode(),还是干脆用 var_export() + eval()(不推荐)或者 igbinary_serialize()(需扩展)。

Tags: serialize PHP数组转成字符串

分享到: