502坏网关:php://输入

时间:2012-02-07 14:38:31

标签: php apache fopen

在php文件中,我正在读取包含图像的输入流。

$incomingData = file_get_contents('php://input');
$fh = fopen($uploadPath, 'w');
fwrite($fh, $incomingData);
fclose($fh);

对于小图像,这种方法很好,对于较大的图像,这需要超过15秒左右,我得到502错误的网关响应。

apache错误日志说:

child pid 1492退出信号分段错误(11)

我尝试了这个但是没有用。

 ini_set('default_socket_timeout', 120);

但我不确定它的暂停时间。

编辑//代码:     

$uploadFilename = time();
$uploadPath = '/path/melvin.jpg';

$fhSrc = fopen('php://input', 'r');

// Valid data?
if($fhSrc) {

    $fhDst = fopen($uploadPath, 'w');

    while (($data = fread($fhSrc, 1024)) !== FALSE) {
        fwrite($fhDst, $data);
    }

    fclose($fhSrc);
    fclose($fhDst);

}

echo 'ok';

RAW HEADERS:

POST /test.php HTTP/1.1
Host: hi.com
User-Agent: secret/1.0 (unknown, iPhone OS 5.0.1, iPhone, Scale/2.000000)
Accept: */*
Accept-Language: nl, en, fr, de, ja, it, es, pt, pt-PT, da, fi, nb, sv, ko, zh-Hans, zh-Hant, ru, pl, tr, uk, ar, hr, cs, el, he, ro, sk, th, id, ms, en-GB, ca, hu, vi, en-us;q=0.8
Accept-Encoding: gzip
Settings: {SOMEJSON}
Content-Type: application/x-www-form-urlencoded
Cookie: CAKEPHP=2b82f748fb3a64063b2e3be9bdec5c11
Connection: keep-alive
Transfer-Encoding: Chunked
Pragma: no-cache
Cache-Control: no-cache

and here in the boy the Big image

1 个答案:

答案 0 :(得分:2)

如果您遇到段错误,此处的问题与超时和内存使用无关。和previously observed here一样,PHP经常处理* nix上的OOM错误的方式是使用段错误。如果你的文件花了15秒钟阅读,那么无论如何你都有一个非常大的文件,所以这并不奇怪!

有几种方法可以解决这个问题。我建议的第一个是最简单的,不涉及乱搞任何配置。您可以将代码更改为此,它应该可以解决问题:

$fhSrc = fopen('php://input', 'r');
$fhDst = fopen($uploadPath, 'w');
stream_copy_to_stream($fhSrc, $fhDst);
fclose($fhSrc);
fclose($fhDst);

如果由于某种原因stream_copy_to_stream()不可用或给您同样的错误,那么快速而又脏的选择是:

while (($data = fread($fhSrc, 1024)) !== FALSE) {
  fwrite($fhDst, $data);
}

这种方法避免了必须将整个文件数据读入PHP的内存空间,并将数据直接从Web服务器缓冲区传输到磁盘 - 因为读取长度为2048 PHP永远不需要更多的2KB工作内存来执行操作。

或者,您可以在php.ini中更改memory_limit指令。我不建议将此作为一种方法,因为除其他原因外,它会降低您的代码的可移植性。