fpasstrhu中允许的内存大小耗尽

时间:2011-03-07 16:33:38

标签: php memory

有没有办法在不超出PHP内存的情况下向浏览器发送大型(大约> 700mb)文件?

我尝试使用fpassthrureadfile,但它超出了内存限制。

4 个答案:

答案 0 :(得分:8)

最有效的解决方案是使用X-Sendfile标头,如果您的网络服务器支持它。

这意味着您无需在提供文件时占用PHP,只需发送标头并让Web服务器处理它。

示例(来自Apache mod_xsendfile页面:)

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

答案 1 :(得分:4)

好老fopen()+ fread()+ fclose():

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

8192是PHP文档中显示的缓冲区大小,但根据我的经验,最好提高它,因为您可以以极少的内存使用量为代价获得有趣的性能提升。

答案 2 :(得分:3)

听起来你使用fpassthru时遇到的问题是由于整个文件被加载到内存中。你应该做的是使用块读取文件数据传统的fopen / fread / fclose周期,随时输出数据。

例如:

<?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...");
?>

答案 3 :(得分:0)

fpassthru(与readfile一样)直接发送数据,而没有太多的内存分配。 因此,缓存和ob_end_flush中的问题会有所帮助:

<?php

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

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

ob_end_flush()

fpassthru($fp);
exit;