PHP. Отдача файла.

DavyJohnes
На сайте с 05.01.2011
Offline
84
1329

Дано: ubuntu 11.10, apache2.2, mod_php

Задача: отдать юзеру файл находящийся на http://othersite.ru с помощью php скрипта находящемся на http:://mysite.ru.

Текущая реализация:

header("Content-disposition:attachment ... и т.д.").

с помощью curl считывается файлик на удаленном сервере и с помощью echo выдается юзеру.

Проблема:

Если файлик весит >100 МБ то процесс затягивается и процесс апача, который выполняет скрипт висит все время скачки в памяти.

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

https://handy-tools.io (https://handy-tools.io) - Набор полезных утилит для всех!
ДП
На сайте с 23.11.2009
Offline
203
#1

По опыту использования извращенных систем php-прокси.

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

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

Это мой личный практический опыт.

edogs software
На сайте с 15.12.2005
Offline
775
#2

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

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

Разработка крупных и средних проектов. Можно с криптой. Разумные цены. Хорошее качество. Адекватный подход. Продаем lenovo legion в спб, дешевле магазинов, новые, запечатанные. Есть разные. skype: edogssoft
DavyJohnes
На сайте с 05.01.2011
Offline
84
#3
Дикий пионер:
По опыту использования извращенных систем php-прокси.
Curl скачивает весь файл в память и отдае его из памяти, поэтому может вываливаться из-за недостата памяти на больших файлах.
Можно отдавать файлы через сокеты - они у меня по памяти никогда не вываливались, даже на шаре хостинге.
Это мой личный практический опыт.
edogs:
При запросе файла запустить отдельным потоком его скачку (вплоть до wget-а, хотя лучше fopen/fgets - что бы легко контроллировать скачку и была возможность ее остановить если вдруг файл юзеру уже не нужен) и получить его размер (получив заголовки с удаленного сервера например, что бы знать когда файл уже скачан полностью). После этого в основном потоке отдавать файл по мере его поступления в файловую систему (т.е. если запрашивают уже несуществующие части, то ждать пока они появятся). При чем в таком виде намного проще поддерживать многопоточность (а с этим наверняка сталкиваетесь, даже если не замечаете).
Отдавать файл разумеется надо считывая и отдавая его небольшими кусочками, тогда даже на php сам скрипт отдачи файла больше пары мегабайт не займет.

А не могли бы вы показать простой пример реализующий описанные вами способы ?

Joker-jar
На сайте с 26.08.2010
Offline
171
#4
Если файлик весит >100 МБ то процесс затягивается и процесс апача, который выполняет скрипт висит все время скачки в памяти.

Если способ не держать процесс апача в памяти на протяжении всего скачивания файла?

Случая два: канал между клиентом и вами уже, чем между вами и mysite. И, соответственно, наоборот. Думаю, первый вариант будет встречаться гораздо чаще. Какой смысл предварительно скачивать файл, если тот же самый процесс Apache будет также висеть, отдавая контент клиенту (если не уходить от Apache совсем)? Можно же тупо перенаправлять запросы клиента (включая заголовки для докачки) и ответ пересылать.

ДП
На сайте с 23.11.2009
Offline
203
#5

Насчет простого примера - это вряд ли сейчас найду, а непростой есть - http://sourceforge.net/projects/poxy/files/PHProxy/0.5%20beta%202/poxy-0.5b2.zip/download

В файле index.php с 524 строки - это отправка запроса, а с 843 - это по сути отдача скачанного контента.

I
На сайте с 23.12.2010
Offline
25
#6
DavyJohnes:
Если способ не держать процесс апача в памяти на протяжении всего скачивания файла? Например скачивать файлик со скоростью большей чем у юзера, складывать его в какой-нибудь буфер на диске, и уже оттуда продолжить отдачу.

сысоев говорит что именно для решения этой задачи он и стал разрабатывать nginx

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий