下载超过 63MB 的文件时出现 500 错误


500 error when downloading files over 63MB

我不确定这是PHP问题,服务器配置问题还是硬件问题,但我想我会从PHP开始,看看我是否得到任何建议。这段代码直到最近才运行良好,我不知道可能导致此问题的任何配置更改。我们最近确实从 Debian Lenny 升级到 Squeeze(从 PHP 5.2 升级到 5.3),但代码在另一台 Squeeze 服务器上运行良好。

我有一些PHP代码,它采用作为GET变量传递的文件的路径(通过mod_rewrite从请求到 http://site.com/request/for/file.pdf 到 http://site.com/downloader.php?path=/path/to/file.pdf 重写)。这样做的原因与统计信息跟踪有关。

文件将传递到此位代码(为便于阅读而简化)。

 if(is_readable($theFile)) {
       //$fh= fopen($theFile, "r");
       header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
       header("Pragma: no-cache");
       header("Content-Type: application/pdf");
       header("Content-Disposition: attachment; filename='"".basename($theFile)."'"");
       header("Content-Length:".(string)(filesize($theFile)));
       sleep(1);
       //fpassthru($fh);
       readfile($theFile);
 }

如您所见,代码仅在文件可读(即路径全部正确)时才执行。对于大约 63MB 以下的文件,一切正常。对于超过 63MB 的任何内容,服务器将返回 500 错误。(这在Firefox/Chrome中被报告为"找不到文件",而我猜它应该是"内部服务器错误",但我想这是另一回事)。Apache错误日志中没有任何内容。

有人能想到任何PHP或Apache服务器配置会导致这种情况发生吗?据我所知,PHP 内存限制不应该受到 readfile 或 fpassthru 的影响。我确实注意到我的PHP内存限制为64MB,但是,关闭mod_rewrite重定向到PHP并不能解决问题。文件仍然无法下载。

非常感谢您的任何建议。

已更新***********

好的,所以我将PHP内存限制从64MB增加到200MB。这允许下载最大200MB的文件。然而,问题仍然存在。鉴于readfile和fpassthru不应受到内存限制的影响,并且我已经检查了输出缓冲是否关闭,为什么大文件会导致这个(新)问题?

分辨率很简单(工作时间后)。

php_value output_buffering 0

添加到 Apache 虚拟主机配置中。

似乎,不管ob_get_level()怎么说,输出缓冲都在发生。换句话说,仅使用输出缓冲的选项就足以影响 PHP 内存的使用。