如何在不耗尽内存的情况下将文件读取给用户(在PHP中)?

时间:2014-04-01 22:26:05

标签: php memory-management file-io buffer

我限制文件未经授权下载,因此只能通过mysite.com/getfile.php?file=32tf2376r327yf等网址下载。我已经知道使用readfile()可以正常工作,但会在发送之前用整个文件填充缓冲区。如果100个用户同时请求它,那将耗尽内存。

相反,我想写出文件的块/行,因为它们已经收到,然后刷新并清除缓冲区,以便随时使用最少的内存。我该怎么做?

伪代码

function sendFile($someFile)
{
    //Start the buffer
    ob_start();

    //Send the headers
    header('Content-type: application/octet-stream');
    header('Content-Disposition: attachment; filename="test.pdf"');
    header('Content-length: ' . (string) (filesize($someFile)));
    ...etc...

    //Get the file (Should I be using "b" mode?)
    $handle = fopen($someFile, "rb");

    if ($handle) {
        //Loop through data, one part at a time
        while (($buffer = fgets($handle, 4096)) !== false) {

            //Send data
            echo $buffer;

            //Flush the buffer
            ob_flush();

            //Clear buffer
            ob_clean();
        }

        //Error...
        if (!feof($handle)) echo "Error: unexpected fgets() fail\n";

        fclose($handle);

        //Make sure everything's sent and clear the buffer
        ob_end_flush();
    }
}

我还需要做些什么来实现我想要做的事情?在PHP中可以吗?

1 个答案:

答案 0 :(得分:-1)

如果您真的关心内存,并且您有理由这样做,那么请使用nginx作为Web服务器,使用php-fpm作为PHP API。

有了这样的设置,绝对没有理由担心任何内存问题。