允许的内存在读取文件时耗尽

时间:2013-11-24 17:35:34

标签: file-io nginx apc php

我正在使用PHP脚本(类似于下面给出的脚本)来传输文件 (服务器堆栈包括nginx + php-fpm + apc

function send_headers($content_type, $filename)
{
    @ob_end_clean();
    header("Content-Type: ".$content_type);
    header("Content-Disposition: attachment; filename=\"".$filename."\"");
    @ob_end_flush();
}

function stream_file($file)
{
    $fp = fopen($file, "r");
    while(true)
    {
        $buffer = fgets($fp, 1024);
        if ($buffer === FALSE)
        {
            break;
        }

        echo $buffer;
        $buffer = NULL;  // unset($buffer) as well gives memory exhaustion error
    }
    fclose($fp);
}

send_headers('text/plain', 'sample.txt');
stream_file('home/linux/report.txt');


在nginx日志中经常记录以下错误

[error] 18391#0: *13673875 FastCGI sent in stderr: "PHP message: PHP Fatal error:
Allowed memory size of 134217728 bytes exhausted (tried to allocate 64 bytes) in
/home/linux/src/library/file.php on line XX" while reading response header from
upstream, client: XXX.XXX.XXX.XXX, server: example.com, request: 
"GET /file/download HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000",
host: "example.com"

为什么php会用这么简单的脚本耗尽128MB的内存?

2 个答案:

答案 0 :(得分:2)

试试这个:

function stream_file($file)
{
    $fp = fopen($file, "r");
    while ($buffer = fgets($fp, 1024))
    {
        echo $buffer;
    }
    fclose($fp);
}

答案 1 :(得分:0)

readfile函数替换stream_file对我有用。我还将文件大小添加到我的标题中。

header('Content-Length: ' . $file->getSize());