$_post 无法直接获取 json 数据,因其仅解析 application/x-www-form-urlencoded 和 multipart/form-data 类型请求;json 请求需通过 php://input 读取原始体并 json_decode 解析,且应依据 content-type 分支处理。

PHP 的 $_POST 不能直接获取 JSON 数据,根本原因在于它的设计职责和底层机制——它只响应特定的 HTTP 内容类型,而 JSON 不在其解析范围内。
$_POST 的作用范围很明确
$_POST 是 PHP 内核在接收到请求后,自动解析并填充的超全局数组,但仅限以下两种 Content-Type:
-
application/x-www-form-urlencoded(如普通表单提交) -
multipart/form-data(如带文件上传的表单)
当浏览器或前端用 fetch、axios 发送 JSON 数据时,通常会设置请求头:
Content-Type: application/json
此时整个请求体是一段原始 JSON 字符串(例如 {"nombre":"fdsf"}),PHP 不会触发任何自动解析逻辑,$_POST 就保持为空数组。
JSON 属于「原始请求体」,必须手动读取
PHP 提供了 php://input 这个只读流,它是访问原始请求体数据的唯一可靠通道。它不依赖 Content-Type,只要请求有 body(且不是 multipart 类型),就能读到全部内容。
所以正确路径是:
- 用
file_get_contents('php://input')拿到原始字符串 - 用
json_decode($raw, true)转成 PHP 关联数组 - 再检查
json_last_error()确保格式合法
常见误解与风险
- ❌ 写
if (!empty($_POST)) { ... } else { /* 处理 JSON */ }:看似合理,实则掩盖协议不一致问题。$_POST在 JSON 请求下天然为空,这个判断永远走 else 分支,但容易让人误以为是逻辑错误而非设计限制。 - ❌ 混用
$_POST和php://input在同一脚本里处理不同来源的数据:比如前端有时发表单、有时发 JSON,却没做 Content-Type 判断,会导致一部分请求永远拿不到数据。 - ❌ 手动拼接 JSON 字符串注入变量(如
"name": "<?php echo $name; ?>"):极易破坏 JSON 结构,引发解析失败,还可能引入 XSS 或 JSON 注入漏洞。
实际判断建议
接收前先看请求头:
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
if (stripos($contentType, 'application/json') === 0) {
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
exit('Invalid JSON');
}
} else {
$data = $_POST; // 仅适用于表单类请求
}
这样既清晰又安全,避免假设、混淆和意外空值。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











