我不确定这是 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,但是,关闭 PHP 的 mod_rewrite 重定向并不能解决问题。文件仍然无法下载。
非常感谢您的任何建议。
已更新***********
好的,所以我将 PHP 内存限制从 64MB 增加到 200MB。允许下载最大 200MB 的文件。然而,问题仍然存在。鉴于 readfile 和 fpassthru 不应受到内存限制的影响,并且我已检查输出缓冲已关闭,为什么大文件会导致此(新)问题?
解决方案很简单(经过几个小时的工作)。
php_value output_buffering 0
添加到 Apache 虚拟主机配置中。
似乎无论 ob_get_level() 说什么,输出缓冲都在发生。换句话说,仅使用输出缓冲的选项就足以影响 PHP 内存使用。
我添加到虚拟主机配置,这导致了错误(没有像 php_value 这样的命令是错误)。然后我添加到/etc/php.ini。我正在等待用户的回复,看看是否解决了问题。但是,如果有人对我在这里发布的内容有回应,我希望看到它。