PHP JSON 处理
本教程共 65 篇 · 第 33 篇 · 更新于 2026-07-24 · 约 5 分钟阅读
33. PHP JSON 处理
本节目标:掌握
json_encode和json_decode的用法,学会处理编码选项和错误,让 PHP 与前端/JavaScript 顺畅交换数据。
JSON(JavaScript Object Notation)是现代 Web 的数据交换标准。PHP 与前端通信、调用第三方 API,几乎都离不开 JSON。
33.1 PHP 数组转 JSON
json_encode() 把 PHP 变量转为 JSON 字符串:
<?php
$user = [
"id" => 1,
"name" => "张三",
"email" => "zhangsan@example.com",
"tags" => ["php", "web"],
"vip" => true,
"balance" => 99.50,
];
$json = json_encode($user);
echo $json;
// {"id":1,"name":"\u5f20\u4e09","email":"zhangsan@example.com","tags":["php","web"],"vip":true,"balance":99.5}
33.2 常用编码选项
json_encode() 的第二个参数是选项位掩码,可组合使用:
<?php
$json = json_encode($user, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
echo $json;
/*
{
"id": 1,
"name": "张三",
...
}
*/
常用选项
| 选项 | 作用 |
|---|---|
JSON_UNESCAPED_UNICODE | 不转义中文字符 |
JSON_PRETTY_PRINT | 格式化缩进输出 |
JSON_UNESCAPED_SLASHES | 不转义 / |
JSON_NUMERIC_CHECK | 把数字字符串转为数字 |
JSON_THROW_ON_ERROR | 出错时抛出异常(PHP 7.3+) |
TipPHP 8.3 起新增了
JSON_INVALID_UTF8_IGNORE和JSON_INVALID_UTF8_SUBSTITUTE,可处理含有非法 UTF-8 序列的数据。
33.3 JSON 转 PHP 变量
json_decode() 把 JSON 字符串转回 PHP 变量:
<?php
$json = '{"id":1,"name":"张三","tags":["php","web"]}';
// 转为对象(默认)
$obj = json_decode($json);
echo $obj->name; // 张三
// 转为关联数组(推荐)
$arr = json_decode($json, true);
echo $arr["name"]; // 张三
深度控制
<?php
// 限制解析深度,防止恶意构造的深层嵌套 JSON
$data = json_decode($deepJson, true, 512, JSON_THROW_ON_ERROR);
33.4 错误处理
JSON 操作失败时,json_encode() 返回 false,json_decode() 返回 null。
PHP 7.3 之前的方式
<?php
$json = json_encode($data);
if ($json === false) {
echo "JSON 编码失败:" . json_last_error_msg();
}
$arr = json_decode($jsonString, true);
if ($arr === null && json_last_error() !== JSON_ERROR_NONE) {
echo "JSON 解码失败:" . json_last_error_msg();
}
PHP 7.3+ 推荐方式
<?php
try {
$json = json_encode($data, JSON_THROW_ON_ERROR);
$arr = json_decode($jsonString, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
echo "JSON 错误:" . $e->getMessage();
}
Note
JSON_THROW_ON_ERROR让 JSON 错误以异常形式抛出,代码更简洁,也不用区分 “合法 null” 和 “解码失败”。
33.5 处理 API 响应
调用第三方接口是最常见的 JSON 场景:
<?php
function fetchApi(string $url): array {
$response = file_get_contents($url);
if ($response === false) {
throw new Exception("请求失败");
}
$data = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
return $data;
}
// 示例:获取天气数据
$weather = fetchApi("https://api.example.com/weather?city=beijing");
echo "温度:" . $weather["temperature"] . "°C";
33.6 处理特殊数据类型
对象序列化
<?php
class User {
public function __construct(
public string $name,
public int $age,
) {}
}
$user = new User("李四", 25);
$json = json_encode($user);
echo $json; // {"name":"李四","age":25}
TipPHP 8.0 的构造函数属性提升(Constructor Property Promotion)让类定义更简洁,上面的
User类会自动拥有$name和$age属性。
排除私有属性
json_encode() 默认只编码 public 属性。可通过 JsonSerializable 接口自定义:
<?php
class Product implements JsonSerializable {
public function __construct(
public string $name,
private float $cost,
) {}
public function jsonSerialize(): mixed {
return [
"name" => $this->name,
"price" => $this->cost * 1.2, // 对外隐藏成本,只暴露售价
];
}
}
$p = new Product("手机", 2000);
echo json_encode($p); // {"name":"手机","price":2400}
33.7 常见错误
- 输出乱码:缺少
JSON_UNESCAPED_UNICODE,中文字符被转义为\uXXXX - 解码得到 null:字符串不是合法 JSON,或超出了最大深度
- 浮点精度丢失:JSON 本身对浮点数支持有限,金额建议用字符串存储
来源:参考了 runoob「PHP JSON」、w3cschool「PHP JSON」等,改写后所得。