Очень большие загрузки с PHP


Я хочу разрешить загрузку очень больших файлов в наше PHP-приложение (сотни мегабайт - 8 гигабайт). Однако с этим есть пара проблем.

Браузер:

  • У загрузок HTML дрянная обратная связь, нам нужно либо опросить о прогрессе (что немного глупо), либо вообще не показывать обратную связь
  • Загрузчик Flash помещает весь файл в память перед началом загрузки

Сервер:

  • PHP заставляет нас устанавливать post_max_size, что может привести в легко эксплуатируемой DOS-атаке. Я бы не хотел устанавливать этот параметр глобально.
  • Серверу также требуются некоторые другие переменные, которые должны присутствовать в POST vars, такие как секретный ключ. Мы хотели бы иметь возможность отклонить запрос сразу, а не после загрузки всего файла.

Требования:

  • HTTP является обязательным.
  • Я гибок в использовании клиентских технологий, пока они работают в браузере.
  • PHP не является обязательным требованием, если есть какие-то другие технология, которая будет хорошо работать в среде Linux, это совершенно круто.
Author: Jon Seigel, 2009-05-14

13 answers

Как насчет Java-апплета? Вот как мы должны были это сделать в компании, в которой я раньше работал. Я знаю, что апплеты отстой, особенно в наши дни, когда доступны все наши возможности, но они действительно являются наиболее универсальным решением проблем, связанных с десктопами, возникающих при веб-разработке. Просто есть над чем подумать.

 3
Author: Marc W, 2009-05-14 17:13:59

Размер файла Upload_max_filesize может быть установлен для каждого каталога ; то же самое относится и к размеру post_max_size

Например:

<Directory /uploadpath/>
  php_value upload_max_filesize 10G
  php_value post_max_size 10G
</IfModule>
 14
Author: Frank Farmer, 2009-05-14 18:44:36

Обработчик Python?

Использование обработчика сообщений Python вместо PHP. Создайте уникальный идентификатор из вашего PHP-приложения, который клиент может поместить в заголовки HTTP. С помощью mod_python, чтобы отклонить или принять большую загрузку до передачи всего тела СООБЩЕНИЯ.

Я думаю http://www.modpython.org/live/current/doc-html/dir-handlers-hph.html

Позволяет проверять заголовки и отклонять остальную часть ввода сообщения. Я не пробовал, но, возможно, это правильный путь?

Глядя на источник mod_python, буферизация входных данных с помощью read(), по-видимому, позволяет поочередно оценивать входные данные HTTP. Заголовки на первом месте.

Https://svn.apache.org/repos/asf/quetzalcoatl/mod_python/trunk/src/filterobject.c

 7
Author: Aiden Bell, 2009-05-14 18:23:08

Я знаю, что это старое, но, возможно, у кого-то сейчас тоже есть эта проблема. Теперь вы можете сделать это только с помощью Javascript и, скажем, PHP. На стороне клиента не требуется Flash или Java.

Демонстрация: http://dnduploader.filkor.org/

Идея состоит в том, чтобы разрезать файлы с помощью метода Javascript Blob slice()...

 7
Author: Filkor, 2012-05-08 21:37:02

Вы можете установить post_max_size только для сценариев в 1 каталоге. Поместите туда свой скрипт загрузки и разрешите только этому скрипту обрабатывать большие размеры. Этот скрипт все еще может быть атакован большими/бесполезными файлами, но он позволяет избежать его глобальной настройки.

Используйте это с APC, и вы, возможно, сможете придумать что-то хорошее: Статья IBM Developer работает над APC

 2
Author: acrosman, 2009-05-14 17:26:19

Попробовал все это... это, безусловно, лучшее, что я использовал до сих пор...

Http://www.uploadify.com/

 2
Author: MichaelICE, 2009-06-02 03:43:44

Взгляните на jumploader.com

Хороший java-апплет для загрузки.

Я использовал его для загрузки изображений, и он отлично работает. Не пробовал работать с файлами размером более 10 МБ, но я должен работать и с действительно большими файлами.

 2
Author: Johan, 2009-07-22 23:25:44

Изучали ли вы возможность использования APC для проверки прогресса и общего размера файла. Вот хороший пост в блоге об этом. Это может помочь.

 1
Author: Peter D, 2009-05-14 17:19:06

Возможно, вы могли бы использовать Webdav и Javascript в браузере

Загрузка большого файла AJAX с прогрессом в WebDAV

Http://www.webdavsystem.com/ajax/programming/upload_progress

Простая библиотека

Http://debris.demon.nl/projects/davclient.js/doc/README.html

Затем вы можете заставить JS перенаправить пользователя на страницу успеха. Секретные ключи и то, что не может быть обработано в прелюдии PHP перед передачей JS Клиент->WebDAV

 1
Author: Aiden Bell, 2009-05-14 17:25:06

Я бы посмотрел FTP, SSH или SCP это позволяет загружать большой файл и при этом иметь контроль доступа к файлу. Это может занять немного больше времени для реализации, но, вероятно, это самый безопасный способ, который я мог придумать.

 1
Author: Phill Pafford, 2009-05-14 17:31:33

У меня был успех с uploadify, и я бы рекомендовал это. Это скрипт jQuery/Flash, который обрабатывает большие загрузки, и вы можете передать ему дополнительные параметры (например, секретный ключ). Чтобы решить проблемы на стороне сервера, просто используйте следующий код. Изменения влияют только на сценарий, в котором они вызываются:

//Check to see if the key is there
if(!isset($_POST['secret_key']) || !isValid($_POST['secret_key']))
{
    exit("Invalid request");
}
function isValid($key)
{
    //Put your validation code here.
}

//This line changes the timeout.
//Give it a value in seconds (3600 = 1 hour)
set_time_limit(3600);

//Set these amounts to whatever you need.
ini_set("post_max_size","8192M");
ini_set("upload_max_filesize","8192M");

//Generally speaking, the memory_limit should be higher
//than your post size.  So make sure that's right too.
ini_set("memory_limit","8200M");

ОТРЕДАКТИРУЙТЕ В ответ на ваш комментарий:

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

Как вы сами сказали, это простой протокол. Помимо написания собственного клиентского программного обеспечения, которое работает вне браузера, java-апплета или использует другой протокол (например, FTP, который был разработан для этого), вы можете не получить то, что хотите.

Я сделал все, что мог, в рамках заданных ограничений. Извини, что я не смог сделать лучше.

 1
Author: Andrew Ensley, 2009-05-14 23:32:48

Я знаю, что отстойно добавлять еще одну зависимость, но, по моему опыту, большинство веб-сайтов, которые делают что-то подобное, используют flash на стороне клиента и загружают большой файл в виде фрагментов

Adobe в качестве инструкции по загрузке файлов flash

Я также нашел этот учебник по codeproject:

Загрузка Нескольких Файлов С Индикатором Выполнения С Помощью Flash и ASP.NET

PS - Я знаю, что вы используете PHP, а не .net, я подумал, что важной частью была вспышка ;)

 0
Author: Jiaaro, 2009-05-14 17:38:15

Попробуйте это: http://www.simple2ftp.com использует FTP-апплет на основе Java из умной оболочки PHP-приложения.

 -1
Author: Henry R., 2013-06-26 19:21:35