为什么readfile()会耗尽PHP内存?

2022-08-30 18:36:20

我看到过很多关于如何有效地使用PHP下载文件而不是允许直接HTTP请求(以确保文件安全,跟踪下载等)的问题。

答案几乎总是PHP readfile()

但是,尽管它在对大型文件进行测试期间效果很好,但是当它在具有数百个用户的实时站点上时,下载开始挂起并且PHP内存限制耗尽。

那么,当流量很高时,导致内存爆炸如此糟糕的工作是什么?我认为它应该通过直接写入输出缓冲区来绕过PHP内存的大量使用?readfile()

编辑:(为了澄清,我正在寻找一个“为什么”,而不是“我能做什么”。我认为Apache mod_xsendfile是规避的最佳方式)


答案 1
Description
int readfile ( string $filename [, bool $use_include_path = false [, resource $context ]] )
Reads a file and writes it to the output buffer*.

PHP必须读取文件并写入输出缓冲区。因此,对于300Mb文件,无论您编写了什么实现(由许多小段或1个大块编写),PHP最终都必须读取300Mb的文件。

如果多个用户必须下载该文件,则会出现问题。(在一台服务器中,托管服务提供商将限制提供给每个托管用户的内存。在内存如此有限的情况下,使用缓冲区不是一个好主意。)

我认为使用直接链接下载文件对于大文件来说是一种更好的方法。


答案 2

如果启用了输出缓冲,则在调用 readfile() 之前使用 ob_end_flush()

header(...);
ob_end_flush();
@readfile($file);

推荐