isJson()仅检查Content-Type头,不验证JSON内容合法性;需配合php://input读取、json_decode解析及json_last_error校验才能确保数据有效。

ThinkPHP 的 request()->isJson() 方法能快速判断当前请求是否为 JSON 类型,但它只检查 Content-Type 头,不验证请求体内容是否真为合法 JSON。
isJson() 判断的是 Header,不是数据本身
该方法内部仅做字符串匹配:stripos($contentType, 'application/json') !== false。这意味着:
- 前端发了
Content-Type: application/json但 body 是空、乱码或纯文本(如abc),isJson()仍返回true - 某些客户端(如 Postman)手动设了 header 却没传 body,
isJson()也会误判 - 它无法区分
application/json;charset=UTF-8和application/json; charset=utf-8等变体,但实际兼容性尚可
真正需要 JSON 数据时,必须手动解析并校验
仅靠 isJson() 不足以支撑业务逻辑,尤其在 API 入口。你应该:
- 先调用
request()->isJson()快速分流,比如把非 JSON 请求直接abort(400) - 再读取
php://input并用json_decode(..., true)解析 - 立即检查
json_last_error() === JSON_ERROR_NONE,否则视为非法 JSON - 对空或全空白字符串提前
trim()过滤,避免json_decode('')返回null却不报错
示例代码:
立即学习“PHP免费学习笔记(深入)”;
$input = file_get_contents('php://input');
if (empty(trim($input))) {
throw new ValidateException('JSON body is empty');
}
$data = json_decode($input, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new ValidateException('Invalid JSON format');
}
混合请求类型下别依赖 isJson() 做数据源选择
如果你的接口同时支持表单提交(application/x-www-form-urlencoded)和 JSON 提交,不能写成:
$data = request()->isJson() ? json_decode(file_get_contents('php://input'), true) : input();
这样有风险:
- 当
isJson()为false时,input()会合并$_GET和$_POST,但 JSON 请求下$_POST为空,容易漏字段 - 如果前端误发了 JSON 内容却没设 header,
isJson()返回false,你就会去读空的$_POST,导致数据丢失 - 更稳妥的做法是:统一读
php://input,再根据是否成功解析 JSON 来决定走哪条路径
异常响应格式由 isJson() 自动触发,但不等于校验可靠
ThinkPHP 在抛出异常时,会调用 isJson() 决定返回 JSON 还是 HTML 错误页。这很省事,但要注意:
- 它只影响异常输出格式,不影响你是否拿到了真实 JSON 数据
- 如果你在控制器里已经手动解析失败并抛出
ValidateException,且此时isJson()返回false,错误仍会以 HTML 形式返回——哪怕前端明明发了 JSON - 因此,建议在解析失败时显式指定响应类型,例如:
return json(['msg' => 'Invalid JSON'], 400);
真正关键的不是“是不是 JSON 请求”,而是“能不能拿到可用的数组”。isJson() 只是个轻量级信号,后面三步(读流、解码、验错)缺一不可。



















