我正在从客户端发送POST请求(使用curl
和自定义nodejs脚本测试)并且无法正确回复响应。整个过程适用于PHP 5.6。
尽可能减少整个事情:
--disable-all --enable-fpm
我正在使用的最小nginx网站配置:
server {
listen 80;
server_name localhost;
location / {
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_pass unix:/var/run/php/php7.0-fpm-api.sock;
fastcgi_param SCRIPT_FILENAME /vagrant/index.php;
}
}
来自/vagrant/index.php
的示例PHP脚本:
<?php
echo str_repeat('.', 512);
flush(); // not necessary, only due testing
curl call我正在使用:curl -XPOST http://localhost/ -H "Transfer-Encoding: chunked" -d ''
我正在使用的NodeJS脚本:
'use strict';
var http = require('http');
var url = require('url');
var uri = url.parse(process.env.URL);
var options = {
method: 'POST', protocol: uri.protocol, hostname: uri.hostname,
port: uri.port, path: uri.path,
};
var data = '';
var httpRequest = http.request(options, function(res) {
res.on('data', function(chunk) {
console.log('received data', chunk.length);
data += chunk;
});
res.on('end', function() { console.log('final size', data.length); });
})
.on('error', function(err) { console.log(err); });
httpRequest.write('');
httpRequest.end();
$ curl http://localhost/
..........[cut off]
$ curl -XPOST http://localhost/ -H "Transfer-Encoding: chunked" -d ''
..........[cut off]
$ URL=http://localhost/ node php7test.js
received data 512
final size 512
$ curl http://localhost/
..........[cut off]
$ URL=http://localhost/ node php7test.js
final size 0
$ curl -XPOST http://localhost/ -H "Transfer-Encoding: chunked" -d ''
curl: (18) transfer closed with outstanding read data remaining
没有商业理由这样做,但我使用的是一个非常相似的NodeJS代码,默认为分块编码,在切换到PHP7时突然停止工作。
我发现以下内容可以从nodejs端开始工作:显式设置Content-Length
标头会删除NodeJS发送的隐式Transfer-Encoding: chunked
标头,从而适用于两个PHP版本。
但是,我想了解为什么PHP7在这里表现不同,以及我是错误还是真的发生了什么。
更新1:
sapi/fpm/
来源,除了PHP内部更改导致的更改之外,我几乎没有差异php -S
)不受影响,所有测试更新2:
我将PHP源分成两部分,并能够确定行为何时发生变化:
在两者之间,来自git bisect
的输出,提交我无法编译:
$ git bisect skip
There are only 'skip'ped commits left to test.
The first bad commit could be any of:
ba5ecf355fe792a5a2a8e6582d5e081d02b16fbf
e383cb4493031a7cd952cfcaed3297e583149c07
fef18f4bea1980a59a9283c2197bd090aaf500cb
18cf4e0a8a574034f60f4d123407c173e57e54ec
We cannot bisect more!
感觉这可能是一个错误,我把它写到内部,也许他们有一些见解:https://marc.info/?l=php-internals&m=145090900217798&w=2
答案 0 :(得分:1)
从您的帖子中我猜测您正在使用 PHP7.0.0 。如果我的猜测是 (bool) TRUE ,那么我建议您迁移到 PHP7.0.1 。
PHP7.0.0 大约 27个错误 被压缩在 PHP7.0.1 ;其他固定项目。
来源:PHP.net changelog。
我还查看了上面的PHP代码(使用我的谷歌眼镜),但它非常简单。我怀疑它有什么不妥。虽然我猜测它与 PHP7 处理 flush() 和输出的方式有关。
注意您的更新(特别是更新1 和更新2 );我必须真的在那里赞美你! 非常令人印象深刻。 请务必查看此修复错误#61751。如果我对你的PHP版本是正确的,那么这个修复过的错误可能已经解决了你的问题;您只需要迁移到 PHP7.0.1 。
注意: 我知道我应该查看修复错误的内部但是......
答案 1 :(得分:0)
它是/ PHP7中的一个错误,最近修复了https://github.com/php/php-src/pull/1745。它还没有在任何正式版本中,但最终会在那里结束一段时间。
在上述PR之前,还报告了一个描述类似问题的错误:https://bugs.php.net/bug.php?id=71466