php://input 仅适用于非表单类原始数据(如JSON/XML),且Content-Type非application/x-www-form-urlencoded或multipart/form-data;需用file_get_contents一次性读取,不可重复调用,不能与$_POST混用,调试时应先验长度和原始字节。
PHP 用
读取原始 POST 数据的适用场景
只有当请求体是纯文本(比如 JSON、XML、自定义二进制)且 Content-Type 不是
或
时,
才能可靠读取原始数据。表单提交用
就够了,硬套
反而拿不到东西。
常见误用场景:前端用
发 JSON,但后端直接查
——结果为空,因为 PHP 不解析 JSON 到
;这时才轮到
上场。
的正确用法和限制
这是最常用也最稳妥的方式,但必须注意三点:
只能读一次,后续再调用会返回空字符串
不能和
或
混用——只要 PHP 解析过表单数据(比如 Content-Type 是
),
就失效了
如果请求用了 chunked transfer encoding,
在某些 PHP 版本(如 5.6 之前)可能不可用
示例:
为什么
容易出错
手动 fopen + fgets 看似灵活,实则埋雷:
立即学习
“
PHP免费学习笔记(深入)
”;
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
没指定长度参数时,
默认只读 1024 字节,大 JSON 直接截断
没处理换行符边界,可能漏掉最后一行(尤其 Node.js 或 Python 客户端发的数据末尾无换行)
PHP 7.4+ 对
的流操作更严格,部分环境会报 Warning
结论:除非你明确要流式解析超大 payload,否则别绕开
。
调试时怎么确认
是否可用
最直接的办法是打印它的长度和前几十个字符,而不是盲目解码:
先检查
,确认不是
或空值
用
看是否为 0 —— 为 0 基本说明被提前消费或编码不匹配
用
查看原始字节,排除 BOM 或不可见控制符干扰
一个容易被忽略的点:Nginx 的
或 Apache 的
如果设得太小,请求根本到不了 PHP,
自然为空——这时候查日志比查代码更快。
php://inputapplication/x-www-form-urlencodedmultipart/form-dataphp://input$_POSTphp://inputfetch$_POST$_POSTphp://inputfile_get_contents('php://input')php://input$_POST$_FILESmultipart/form-dataphp://inputphp://input$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
if (json_last_error() !== JSON_ERROR_NONE) {
// 处理解析失败
}fgets(fopen('php://input', 'r'))fgetsphp://inputfile_get_contentsphp://input$_SERVER['CONTENT_TYPE']multipart/form-datastrlen(file_get_contents('php://input'))bin2hex(substr(file_get_contents('php://input'), 0, 32))client_max_body_sizeLimitRequestBodyphp://input