开发者

Allowed memory size exhausted in fpasstrhu

Is there a way to send a large (about >700mb开发者_高级运维) file to the Browser without exceeding memory in PHP?

I tried using fpassthru and readfile and it exceedet the memory limit.


The most efficient solution would be to use the X-Sendfile header, if your webserver supports it.

It means you don't need to occupy PHP at all with serving the file, you just send the header and let the web server handle it.

Example (from the Apache mod_xsendfile page:)

header("X-Sendfile: $path_to_somefile");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$somefile\"");
exit;


Good old fopen() + fread() + fclose():

<?php
$handle = fopen('/tmp/foo', 'rb');
while (!feof($handle)) {
    echo fread($handle, 8192);
}
fclose($handle);

8192 is the buffer size shown in PHP documentation but in my experience it's better to raise it because you can get an interesting performance boost at the price of very little memory usage increase.


It sounds like the problems you're having using fpassthru are due to the whole file being be loaded into memory. What you should instead do is read the file data in chunks using the traditional fopen/fread/fclose cycle, outputting the data as you go.

For example:

<?php
    $fileRes = fopen('/path/to/your/file.data', 'rb');
    if(is_resource($fileRes) {
        while (!feof($fileRes)) {
            echo fread($fileRes);
        }
        fclose($fileRes);
    }
    else die("Couldn't open file...");
?>


fpassthru (as readfile) sends data directly, without much memory allocation. So problem in caching and ob_end_flush will help:

<?php

$fp = fopen($filename, 'rb');

header('Content-Type: ' . mime_type($filename));
header("Content-Length: " . filesize($filename));

ob_end_flush()

fpassthru($fp);
exit;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜