PHP JSON 教程:编码解码与常见坑
一、什么是 JSON
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,广泛用于前后端数据传输和 API 接口开发。PHP 内置了完整的 JSON 支持,无需额外安装扩展(PHP 5.2+)。
二、json_encode:把 PHP 数据转成 JSON
<?php
$data = [
'name' => '张三',
'age' => 25,
'hobby' => ['读书', '跑步']
];
$json = json_encode($data);
echo $json;
输出结果:
{"name":"\u5f20\u4e09","age":25,"hobby":["\u8bfb\u4e66","\u8dd1\u6b65"]}
可以看到中文被转成了 Unicode 转义。如果想让中文原样输出,加上 JSON_UNESCAPED_UNICODE 参数:
$json = json_encode($data, JSON_UNESCAPED_UNICODE);
echo $json;
// {"name":"张三","age":25,"hobby":["读书","跑步"]}
三、json_decode:把 JSON 转回 PHP 数据
<?php
$json = '{"name":"张三","age":25}';
// 默认返回对象
$obj = json_decode($json);
echo $obj->name; // 张三
// 第二个参数传 true,返回关联数组
$arr = json_decode($json, true);
echo $arr['name']; // 张三
注意:json_decode 默认返回 object 类型,实际开发中更推荐用 true 转成数组,操作起来更方便。
四、处理解析失败:json_last_error
当 JSON 格式不合法时,json_decode 会返回 null,此时可以用 json_last_error() 查看错误原因:
<?php
$badJson = "{name:'张三'}"; // 键名没用双引号,非法 JSON
$arr = json_decode($badJson, true);
if (json_last_error() !== JSON_ERROR_NONE) {
echo '解析失败:' . json_last_error_msg();
}
// 解析失败:Syntax error
常见错误码对应的问题:
JSON_ERROR_SYNTAX:语法错误,最常见,比如单引号、末尾多余逗号JSON_ERROR_UTF8:数据不是合法的 UTF-8 编码JSON_ERROR_DEPTH:嵌套层级超过上限(默认 512)
五、常见坑
1. 中文变成 \uXXXX
前面已提过,加 JSON_UNESCAPED_UNICODE 即可。
2. 斜杠被转义
URL 中的 / 会被转成 \/,可加 JSON_UNESCAPED_SLASHES:
$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
3. 输出接口时别忘了设置响应头
<?php
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data, JSON_UNESCAPED_UNICODE);
如果不设置 Content-Type,前端某些框架可能不会自动按 JSON 解析。
4. 空对象与空数组
PHP 中空数组 [] 被 json_encode 后是 [],有时你希望它是对象 {},可以强制转换:
json_encode((object)[]); // {}
六、一个完整的接口示例
<?php
header('Content-Type: application/json; charset=utf-8');
$userList = [
['id' => 1, 'name' => '张三'],
['id' => 2, 'name' => '李四'],
];
echo json_encode([
'code' => ,
'msg' => 'success',
'data' => $userList,
], JSON_UNESCAPED_UNICODE);
返回:
{
"code": ,
"msg": "success",
"data": [
{"id": 1, "name": "张三"},
{"id": 2, "name": "李四"}
]
}
七、小结
json_encode负责编码,json_decode负责解码,记住第二个参数true转数组- 中文乱码用
JSON_UNESCAPED_UNICODE,接口输出记得设置响应头 - 解析失败别慌,用
json_last_error()和json_last_error_msg()定位问题