【问题标题】:502 bad gateway: php://input502 错误网关:php://input
【发布时间】:2012-02-28 23:50:34
【问题描述】:

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

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

对于小图像,这工作得很好,对于需要超过 15 秒左右的大图像,我得到 502 bad gateway 响应。

apache 错误日志说:

child pid 1492 exit signal Segmentation fault (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';

原始标题:

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

【问题讨论】:

  • set_time_limit() 有帮助吗?
  • 检查 php 错误日志。我认为您正在达到内存限制,因为您将图像缓冲成字符串。无论如何,更有效的方法是 copy('php://input', $destination);
  • 不,max_input_time() 或 max_execution_time() 也没有
  • @chris copy() 确实有效,但给出了完全相同的问题。还有其他解决方案吗?与此同时,当我试图阅读我的 php 错误日志时。
  • 我评论的要点是您需要检查 php 错误日志。通过phpinfo() 找到它的位置;您可能需要通过ini_set() 将error_log 设置为位置,将log_errors 设置为打开,将error reporting 设置为E_ALL 来指定它

标签: php apache fopen


【解决方案1】:

如果您遇到段错误,这里的问题与超时无关,而是与内存使用有关。与previously observed here 一样,PHP 经常在 *nix 上处理 OOM 错误的方式是使用 segfault。如果您有一个文件需要 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 指令。我不推荐这种方法,因为除其他原因外,它会降低您的代码的可移植性。

【讨论】:

  • 这两个选项都适用于较小的文件。但是对于更大的文件,我总是遇到同样的错误。限制约为 600.00/700.00 kb。我将使用我现在拥有的代码编辑我的第一篇文章。我希望你能帮助我。
  • 这绝对不是时间限制,我猜一些 PHP ini 限制左右。但是找不到哪个。
  • 我猜你有没有办法改变传入消息的格式?如果可以的话,我很想看看你是否仍然遇到multipart/form-data 文件上传和使用$_FILES 数组的问题... syslog 中有什么有用的(如在操作系统日志文件中)?
  • 另外我注意到您的消息有一个 Content-Typeapplication/x-www-form-urlencoded 并且您说您将原始图像作为消息正文发送 - 这没有语义意义,请求的 Content-Type:应该是图像的,例如image/jpeg
  • 将 Content-type 设置为 image/jpeg 有效。我现在可以发送大于 1 MB 的数据。但其奇怪的想法。为什么我会为此在 directadmin 中遇到分段错误?谢谢顺便说一句,你救了我的命:P
猜你喜欢
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 2012-04-17
  • 2011-03-12
  • 1970-01-01
  • 1970-01-01
  • 2017-03-28
  • 1970-01-01
相关资源
最近更新 更多