«Разрешенная память .. исчерпана» при использовании readfile

Я создал скрипт загрузки на PHP, который работал до вчерашнего дня. Сегодня я попытался загрузить один из файлов, чтобы обнаружить, что он вдруг перестает работать:

PHP Неустранимая ошибка: допустимый размер памяти 67108864 байт исчерпан (пытался выделить 119767041 байт) в E: \ home \ tecnoponta \ web \ aluno \ download.php в строке 52

По какой-то причине 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; 

От php.net для файла readfile :

readfile () не представляет проблем с памятью, даже при отправке больших файлов, сам по себе. Если вы столкнулись с ошибкой вне памяти, убедитесь, что буферизация вывода отключена с помощью ob_get_level ().

От php.net для ob_clean :

Эта функция не уничтожает выходной буфер, такой как ob_end_clean ().

Что вам нужно, так это:

 if (ob_get_level()) { ob_end_clean(); } 

Также подумайте над добавлением этого:

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

Решение ob-level всегда давало пустой результат.

Это решение работает для меня:

 <?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; } ?> 

Таким образом, используя stream_copy_to_stream() вместо fileread()

Надеюсь, это может вам помочь.

Размер файла больше, чем предел памяти php.

Делать

 ini_set('memory_limit','16M'); 

И установите часть «16M», по крайней мере, в файл.