php, file загрузить

Я использую простой скрипт загрузки файлов:

if (file_exists($file)) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename='.basename($file)); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . filesize($file)); ob_clean(); flush(); readfile($file); exit; } 

Он работает на моем локальном сервере до 200 мб.

Когда я пытаюсь использовать этот код на своем веб-сайте, он загружает 173 КБ вместо 200 МБ-файла.

Я проверил все, написал какой-то пользовательский код (используя функции ob и fread вместо readfile), но не могу загрузить большие файлы.

Спасибо за ответ.

  • Я использую Apache 2.2, PHP 5.3
  • Все настройки PHP для работы с большими файлами в порядке. (время выполнения, пределы памяти, …

Solutions Collecting From Web of "php, file загрузить"

Одна из проблем, которые у меня есть со следующим кодом, заключается в том, что у вас нет контроля над потоком вывода, позволяя PHP обрабатывать его, не зная точно, что происходит в фоновом режиме:

Что вам нужно сделать, так это настроить систему вывода, в которой вы можете управлять и реплицировать серверы accros.

Например:

 if (file_exists($file)) { if (FALSE!== ($handler = fopen($file, 'r'))) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename='.basename($file)); header('Content-Transfer-Encoding: chunked'); //changed to chunked header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); //header('Content-Length: ' . filesize($file)); //Remove //Send the content in chunks while(false !== ($chunk = fread($handler,4096))) { echo $chunk; } } exit; } echo "<h1>Content error</h1><p>The file does not exist!</p>"; 

Это только базовая задача, но приготовьтесь!

Также прочитайте мой ответ здесь: file_get_contents => PHP Неустранимая ошибка: Допустимая память исчерпана

Кажется, что readfile может иметь проблемы с длинными файлами. Как сказал @Khez, возможно, скрипт работает слишком долго. В результате быстрого Googling появилось несколько примеров разбивки файла.

http://teddy.fr/blog/how-serve-big-files-through-php http://www.php.net/manual/en/function.readfile.php#99406

Одним из решений некоторых сценариев является то, что вы можете использовать PHP-скрипт для разумного решения, какой файл загружать, но вместо отправки файла непосредственно с PHP вы можете вернуть перенаправление клиенту, который затем содержит прямую ссылку, которая обрабатывается только веб-сервером.

Это можно сделать, по крайней мере, двумя способами: либо PHP-скрипт копирует файл в «зону загрузки», которая, например, может быть очищена из «старых» файлов регулярно каким-либо другим фоновым / служебным скриптом, либо вы обнаружите реальное постоянное место для клиентов.

Конечно, есть недостатки, как в случае с каждым решением. В этом заключается то, что в зависимости от клиентов (завиток, wget, GUI-браузера), запрашивающих файл, они могут не поддерживать перенаправление, которое вы делаете, а в другом – файлы очень подвержены внешнему миру и могут быть прочитаны всегда без (доступ) для скрипта PHP.

Вы уверены, что ваш скрипт может работать достаточно долго и иметь достаточно памяти?

Вам действительно нужна буферизация вывода?

Реальное решение состоит в том, чтобы избежать использования PHP-скрипта для просто отправки файла клиенту, это слишком много, и ваш веб-сервер лучше подходит для задачи.

Предположительно, у вас есть причина для отправки файлов через PHP, возможно, сначала пользователи должны пройти аутентификацию? Если это так, вы должны использовать X-Accel-Redirect (если вы используете nginx) или X-Sendfile (ранее X-LIGHTTPD-send-file) на lighttpd.

Если вы используете Apache, я нашел несколько ссылок на mod_xsendfile, но я никогда не использовал его лично, и я сомневаюсь, что он установлен для вас, если вы управляете хостингом.

Если эти решения несостоятельны, я приношу свои извинения, но мне действительно нужна дополнительная информация о реальной проблеме: почему вы отправляете эти файлы через PHP в первую очередь?