使用file_get_contents('php://input')获取原始数据返回NULL的问题
遇到这种情况太头疼了,我之前调试接口的时候也多次碰到过,咱们一个个排查可能的问题:
1. 请求Content-Type不兼容
如果你的请求用了multipart/form-data(比如带文件上传的表单),PHP会自动把POST数据解析到$_POST和$_FILES里,不会把数据留在php://input中,这时候读它自然就是NULL。
- 解决办法:
- 如果是纯数据传输(比如JSON、普通文本),把请求的Content-Type设为
application/json或application/x-www-form-urlencoded; - 如果确实需要用
multipart/form-data,直接从$_POST和$_FILES里取数据就行。
- 如果是纯数据传输(比如JSON、普通文本),把请求的Content-Type设为
可以先打印当前请求的Content-Type确认:
var_dump($_SERVER['CONTENT_TYPE']);
2. php://input已经被提前读取过
php://input是一次性流,如果你的代码(或者你用的框架中间件)已经通过其他方式读取过它(比如用fopen('php://input', 'r')、重复调用file_get_contents,或者某些框架的请求解析逻辑),再次读取就会得到NULL。
- 解决办法:
- 检查代码流程,确保没有提前读取php://input;
- 如果用框架,直接用框架提供的请求对象获取原始数据(比如Laravel里的
$request->getContent()); - 实在不行,可以尝试用
php://stdin替代,但这个在某些CGI环境下可能和php://input表现一致。
3. PHP配置限制导致数据未被读取
如果php.ini里的enable_post_data_reading被设置为Off,PHP会跳过POST请求体的读取,这时候php://input必然是空的。
- 解决办法:
- 打开php.ini文件,找到
enable_post_data_reading配置; - 把它改成
On; - 重启你的Web服务器(Apache/Nginx)和PHP-FPM(如果用的话)。
- 打开php.ini文件,找到
你可以用phpinfo()函数查看当前的配置值:
phpinfo();
4. 请求方式不对
如果你的请求是GET方式,请求体不会被PHP处理,php://input自然是空的——GET的参数都在URL的query string里,应该用$_GET或者$_REQUEST获取。
- 解决办法:确保发送请求时用的是POST、PUT、PATCH这类带请求体的HTTP方法。
5. 请求数据量超过配置上限
如果发送的数据大小超过了php.ini里的post_max_size或upload_max_filesize,PHP会截断甚至拒绝处理请求体,导致php://input返回NULL。
- 解决办法:
- 修改php.ini里的
post_max_size(比如设为10M)和upload_max_filesize(建议和post_max_size保持一致或更大); - 如果用Nginx,还要检查
client_max_body_size配置,确保它的值不小于post_max_size,否则Nginx会直接拒绝大请求; - 重启相关服务。
- 修改php.ini里的
6. 服务器/网关的配置问题
比如Nginx的某些fastcgi配置错误,导致请求体没有正确传递给PHP-FPM。比如如果设置了fastcgi_param CONTENT_LENGTH "";,会让PHP无法识别请求体的长度,从而不读取数据。
- 解决办法:检查Nginx的fastcgi配置,确保保留默认的
fastcgi_param CONTENT_LENGTH $content_length;,并且没有其他干扰请求体传递的配置。
内容的提问来源于stack exchange,提问作者Mirnamiq Abdullayev

