Я создал скрипт загрузки на 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», по крайней мере, в файл.