【问题标题】:NGINX/PHP - Cannot serve jpeg via php scriptNGINX/PHP - 无法通过 php 脚本提供 jpeg
【发布时间】:2018-04-05 19:01:23
【问题描述】:

以下脚本很简单,可以在 apache 上正常运行,没有问题

header('Content-Type: image/jpeg');
echo file_get_contents('./photo.jpg');

在 NGINX/PHP-FPM 上,我得到一个空白页。我尝试了两个不同的虚拟服务器。我创建的一个,以及基于 Laravel Homestead 的宅基地改进框 (https://github.com/Swader/homestead_improved)。

错误报告已开启,没有错误。如果我删除标题并使用:

echo file_get_contents('./photo.jpg');

我将二进制转换为 ASCII 并看到奇怪的字符;文件正在正确加载。

我认为问题可能是缺少标题,所以我尝试了内容长度:

header('Content-Type: image/jpeg');
$contents =  file_get_contents('./photo.jpg');

header('Content-length: ' . strlen($contents));
echo $contents;

这给出了不同的结果:页面永远不会加载,就好像浏览器永远不会收到它所期望的所有字节。

如果我打印strlen($contents),它会以字节为单位显示文件大小。 PHP 正在正确加载图像,但它从未到达浏览器。

该脚本在 Apache 服务器上运行,因此问题似乎是 NGINX 或 PHP-FPM。

我尝试了不同的图像(一张 80kb,一张 2.2mb),结果是一样的。我也试过readfile 而不是file_get_contents

更新

在 Chrome 开发者工具中,完整的图像被下载并显示在“网络”标签中。浏览器正在获取数据,但未显示。

【问题讨论】:

  • 使用Content-Disposition inline
  • 不幸的是,这没有帮助。不过,它似乎是某种缺失的标题。 Firefox 或 Chrome 都无法显示该图像。如果我直接导​​航到 photo.jpg,他们可以很好地显示它
  • 由于它在 Apache 中工作,也许您可​​以并排比较标头,看看有什么不同/缺少什么。我确实认为readfile() 是更好的方法。你知道是否启用了输出缓冲吗?它在许多 PHP 安装中默认启用。在调用 readfile() 之前尝试调用 ob_end_flush()
  • Chrome/Firefox 接收到的标头是什么样的?

标签: php nginx


【解决方案1】:

您的问题在于进程内存。 PHP 在 PHP-FPM 下运行时和在 Apache 下运行时使用不同的配置文件。

file_get_contents 的问题在于它将整个文件读入内存。在图像文件的情况下,内存达到其极限,http 响应永远不会完成。

要解决此问题,您可以使用fopen 流式传输图像或增加 PHP-FPM php 的内存限制。

【讨论】:

    【解决方案2】:

    就像 Scriptonomy 所说,内存可能是个问题。你也可以使用readfile

    https://secure.php.net/manual/en/function.readfile.php

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-26
      • 1970-01-01
      • 2018-03-29
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多