当前位置:  开发笔记 > 编程语言 > 正文

使用分块编码对PHP7的POST请求无法正确返回结果

如何解决《使用分块编码对PHP7的POST请求无法正确返回结果》经验,为你挑选了0个好方法。

我正在从客户端发送POST请求(使用curl和自定义nodejs脚本测试)并且没有正确地返回响应.整个过程适用于PHP 5.6.

环境

整个事情尽可能减少:

在Vagrant VM Ubuntu 14.04 LTS内部运行的所有内容

来自http://nginx.org/packages/ubuntu/的 nginx 1.9.7

从官方来源编译的PHP7 FPM --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;
  }
}

示例PHP脚本来自/vagrant/index.php:



我正在使用的卷曲电话: 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();

将我的测试请求发送到PHP 5.6

$ 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

将我的测试请求发送到PHP 7.0

$ 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/5.6和7.0之间的来源,除了由于PHP内部变化引起的变化之外,我几乎没有差异

php -S所有测试都不会影响内置服务器()

更新2:

我将PHP源分成两部分,并能够确定行为何时发生变化:

我能够编译的最后一次提交有效:https: //github.com/php/php-src/commit/16265a59ac6bd433bfb636e4e44da1ad57cdcda9

第一次提交我能够再次编译哪些不起作用:https://github.com/php/php-src/commit/86de98cabada88f4667839794c176ea37648498b

在其间,输出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

推荐阅读
围脖上的博博_771
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有