使用readfile时"允许内存耗尽"

bru*_*uno 3 php file

我用PHP编写了一个下载脚本,直到昨天.今天我试着下载其中一个文件,发现它突然停止了工作:

PHP致命错误:第52行的E:\ home\tecnoponta\web\aluno\download.php中允许的内存大小为67108864字节(尝试分配119767041字节)

出于某种原因,PHP试图在内存中分配文件的大小,我不知道为什么.如果文件大小小于内存限制,我可以毫无问题地下载它,问题在于更大的文件.

我知道可以通过增加php.ini中的内存限制甚至在代码上使用ini_set来纠正它,但我想要一个更准确的方法来解决这个问题以及为什么它停止工作的答案.

这是我的代码:

$file = utf8_decode($_GET['d']);

header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename='.$file);
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');

$file = "uploads/$curso/$file";

ob_clean();
flush();
readfile($file);

echo "<script>window.history.back();</script>";
exit;
Run Code Online (Sandbox Code Playgroud)

Cli*_*tle 15

php.net获取readfile:

即使在发送大文件时,readfile()也不会出现任何内存问题.如果遇到内存不足错误,请确保使用ob_get_level()关闭输出缓冲.

来自php.net的ob_clean:

此函数不像ob_end_clean()那样破坏输出缓冲区.

你需要的是这个:

if (ob_get_level()) {
      ob_end_clean();
    }
Run Code Online (Sandbox Code Playgroud)

还考虑添加这个:

header('Content-Length: ' . filesize($file));
Run Code Online (Sandbox Code Playgroud)


Al-*_*ani 5

ob级解决方案始终导致输出为空。

此解决方案适用于我:

<?php


$myFile = $myPath.$myFileName;

if (file_exists($myFile)) {


header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$myFileName.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($myFile));

//alternative for readfile($myFile);

$myInputStream = fopen($myFile, 'rb');
$myOutputStream = fopen('php://output', 'wb');

stream_copy_to_stream($myInputStream, $myOutputStream);

fclose($myOutputStream);
fclose($myInputStream);

exit;

} else {

echo "*** ERROR: File does not exist: ".$myFile;

}

?>
Run Code Online (Sandbox Code Playgroud)

所以用stream_copy_to_stream()代替fileread()

希望这可以帮到你。