PHP:如何使用传输编码读取 POST 正文:分块,无内容长度


PHP: How to read POST body with Transfer-Encoding: chunked, no Content-Length

我正在编写一个服务,用于从我家的能源监控设备接收数据。设备推送数据的唯一方法是使用 HTTP POSTTransfer-Encoding: chunked,没有Content-Length,并在请求正文中将数据作为 XML。

我希望能够在PHP脚本(在Apache后面)中读取这些数据并将其存储在我的数据库中。

看来,如今在 PHP 中读取 HTTP 请求正文的最正确方法是打开并读取php://input。但是,PHP网站上的用户评论表明(我的测试证实了),如果客户端没有指定Content-Length标头,则php://input返回任何数据(即使客户端以分块编码发送数据)。

是否有访问请求正文的替代方法?我可以配置 Apache(使用 .htaccess)来解码分块数据并在获取全部数据后调用我的脚本并包含Content-Length吗?或者配置 PHP 以便它能够处理这个问题?

谢谢!

我想不妨

把这个写成答案。

您描述的问题记录在此处:https://bugs.php.net/bug.php?id=60826

线程的亮点:

这就是我的发现。如果您发送分块 http 请求但没有 发送内容长度(我们应该使用 HTTP 1.1 协议)的 请求的正文部分为空(php://input 不返回任何内容)。这 结果对于运行 PHP 的以下配置仍然有效 通过快速CGI:

PHP 运行的相同配置mod_php很好,正文 可通过 php://input 提出请求。

从本质上讲,PHP 遵循规范,而不是阅读超出 FastCGI CONTENT_LENGTH标头值 - 因此正确的修复是 必须在PHP之上,在FastCGI或Web服务器实现中。

可能的解决方法:

0) 将 httpd 与 mod_php

一起使用

1) 使用不同的 Web 服务器。

2)查看补丁mod_fcgid

3)也许(不推荐)翻转always_populate_raw_post_data看看$HTTP_RAW_POST_DATA中是否有任何东西