PHP JSON 处理:抛出解码异常并校验任务字段
解码任务 JSON 后分别验证根节点与字段类型,用 JSON_THROW_ON_ERROR 区分语法错误和业务错误,并保留中文可读输出。
本节目标
解码任务 JSON 后分别验证根节点与字段类型,用 JSON_THROW_ON_ERROR 区分语法错误和业务错误,并保留中文可读输出。
环境与运行方法
使用 PHP 8.2 或更新版本的命令行解释器。保存为 lesson.php,先执行 php -l lesson.php 检查语法,再运行 php lesson.php。代码不需要 Web 服务器。
核心思路
JSON 语法合法并不代表字段符合要求。本例需要一个任务对象,标题为非空字符串,done 为布尔值。使用对象解码后检查 stdClass,可以区分任务对象与普通列表。
完整示例
<?php
declare(strict_types=1);
function task(string $json): stdClass {
$value = json_decode($json, false, 512, JSON_THROW_ON_ERROR);
if (!$value instanceof stdClass
|| !isset($value->title) || !is_string($value->title)
|| trim($value->title) === ""
|| !isset($value->done) || !is_bool($value->done)) {
throw new InvalidArgumentException("invalid task");
}
return $value;
}
foreach (['{"title":"复习","done":false}', '{"title":"坏数据","done":"false"}'] as $text) {
try {
echo json_encode(task($text), JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR), "\n";
} catch (JsonException | InvalidArgumentException $error) {
echo "invalid\n";
}
}预期输出
{"title":"复习","done":false}
invalid逐步理解
第一项读取后仍然拥有布尔 false,并以可读中文编码输出。第二项的 done 是字符串,不能因为看起来像 false 就当成布尔值。isset 对 false 返回真,因此合法未完成状态不会丢失。
JsonException 处理语法层失败,InvalidArgumentException 表示结构或业务字段不符。本例允许额外字段,若用于严格网站导入,可以在验证后构造只含允许字段的新对象。输出模式不会自动删掉不需要的数据。
常见问题与边界
- 不要把字符串 false 强转成布尔值作为 JSON 校验。
- 使用异常模式时要在合适调用边界捕获。
- 深度限制和最大输入长度属于导入边界,不能无限接受外部内容。
动手练习
把输入改成 []、空白标题和真正的 done=true。
参考答案
列表与空白标题失败,布尔 true 通过。语法解析、结构校验、业务范围应分别检查,而不是只看 json_decode 是否返回非空。
文章回复
0 条公开回复