PHP接收前端JSON数据必须手动读取php://input并json_decode(true)解析,不能依赖$_POST;需校验Content-Type、检查json_last_error(),且php://input仅可读一次、不与multipart/form-data共存。

PHP 接收前端传来的 JSON 数据,核心在于:不能依赖 $_POST,必须手动读取原始请求体并解析。因为 PHP 只对 application/x-www-form-urlencoded 和 multipart/form-data 类型自动填充 $_POST,而 application/json 属于原始数据流,需显式处理。
✅ 正确接收 JSON 的标准流程
- 使用
file_get_contents('php://input')读取原始请求体(仅限 POST/PUT/PATCH 等有 body 的请求) - 用
json_decode($json, true)解析为关联数组(第二个参数true很关键) - 检查
json_last_error()确保解析成功 - 校验
Content-Type头是否为application/json(防误触发或绕过)
示例代码:
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
if (strpos($contentType, 'application/json') !== 0) {
http_response_code(415);
echo json_encode(['error' => 'Content-Type must be application/json']);
exit;
}
$json = file_get_contents('php://input');
if ($json === false || $json === '') {
http_response_code(400);
echo json_encode(['error' => 'Empty request body']);
exit;
}
$data = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
echo json_encode(['error' => 'Invalid JSON format']);
exit;
}
// 安全访问字段
$name = $data['name'] ?? null;
if (is_string($name) && !empty($name)) {
echo "Hello, $name";
} else {
echo "Missing or invalid name";
}⚠️ 常见错误与注意事项
-
$_POST在 JSON 请求下始终为空,写if (!empty($_POST))判断会永远走错分支 -
php://input只能读一次,重复调用返回空字符串 - 不能和
enctype="multipart/form-data"共存(上传文件时无法同时读 JSON) -
json_decode($json)默认返回对象,要用$obj->name;加true才返回数组,支持$arr['name']和isset() - 中文或特殊字符乱码?确保前端发送的是 UTF-8 编码,且未带 BOM 头
? 前端发送示例(供对照)
JavaScript fetch:
fetch('/api.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: "张三", age: 28 })
});Postman 设置:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
立即学习“PHP免费学习笔记(深入)”;
- Body → raw → JSON
- Headers 中手动添加
Content-Type: application/json
? 如果要兼容 JSON 和表单两种格式?
不建议混用,但若必须支持,可按 Content-Type 分支处理:
- 是
application/json→ 走php://input + json_decode - 是
application/x-www-form-urlencoded→ 直接用$_POST - 注意:不要同时检查
$_POST和php://input,逻辑会冲突
实际部署中,90% 的 JSON 接收失败都源于三点:
- 前端没设
Content-Type: application/json - Nginx/Apache 未透传
CONTENT_TYPE(尤其 Nginx 需配fastcgi_pass_request_headers on;) - 本地开发用了代理(如 Vite Proxy),但代理默认不转发
Content-Type
抓包看请求头和 body,比盲调代码更高效。


















