如何让Apache停止缓冲POST数据?

4
当通过XHR流式传输文件到在Apache Web服务器上运行的PHP脚本时,某些东西会缓冲整个POST正文,然后在整个文件上传完毕后将其交给PHP。这非常消耗内存且不理想。我有另一台配置大致相同的服务器,它直接将POST数据流式传输到PHP脚本,从而导致内存使用量较低。但是我无法找出配置差异所在。是否有任何明显的设置(例如“BufferPostBody Yes”)需要查找?
到目前为止,我尝试了以下方法: 禁用mod_security 通过HTTP而不是HTTPs发送文件 检查Apache日志、PHP日志和syslog。没有错误或警告。
我如何测试此行为: 通过JS上传大文件(235M)通过XHR流式传输。一旦请求开始,PHP应输出“performing upload”。但实际情况是只有在整个文件通过POST上传后才会看到“performing upload”。
坏服务器上加载的模块列表如下: core mod_log_config mod_logio prefork http_core mod_so mod_alias mod_auth_basic mod_authn_file mod_authz_default mod_authz_groupfile mod_authz_host mod_authz_user mod_autoindex mod_cgi mod_dir mod_env mod_mime mod_negotiation mod_php5 mod_reqtimeout mod_rewrite mod_setenvif mod_ssl mod_status mod_unique_id

请问在脚本顶部调用ob_end_clean()一次是否保证了ob_flush()的执行? - Eric Uldall
2
这不是重复问题。我的问题涉及输入而非输出缓冲。问题不在于PHP等待提供脚本输出,而在于Apache向PHP脚本提供输入。 - HackaZach
也许不是Apache“缓存”POST输入数据,而是PHP希望在您的脚本开始之前处理所有数据。我没有测试过,但我看到了enable_post_data_reading ini设置,PHP将不会填充$_POST$_FILES,您需要自己处理POST数据。 - hakre
使用 PUT 将大致实现您在此处想要的内容;PHP 可以从 php://input 中获取。 - Ja͢ck
2个回答

3
你需要将PHP设置中的enable_post_data_reading设置为Off。我发现这是PHP请求缓冲的原因,因此不允许流像流一样工作。 http://php.net/manual/en/ini.core.php#ini.enable-post-data-reading 这会禁用$_POST$_FILES变量,因此,如果你在应用程序的其余部分中使用它们,可能会有问题。
为了解决这个问题,我有一个Apache配置,只在特定条件下启用它。
在这种情况下,是基于Location和Content Type的。
<Location /uri/to/path/file.php>
    <If "req('Content-Type') = 'application/customfiletype'">
        php_value enable_post_data_reading Off
    </If>
</Location>

1
PHP假设整个POST请求可用,因此在启动PHP之前等待POST完成是按设计的,我认为这可能是不可避免的。您可以使用浏览器中的HTML5文件API拆分文件,然后逐个发送文件块,每个块都在自己的PHP POST请求中。如何使用HTML5在浏览器中拆分文件的示例:http://www.html5rocks.com/en/tutorials/file/dndfiles/ HTML5文件API的浏览器支持:http://caniuse.com/#feat=fileapi(不适用于IE<10 :()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接