В настоящее время я использую следующую функцию PHP, чтобы пользователь мог выбрать файл, а затем загрузить его. Это происходит по FTP. Однако, если пользователь выбирает большой файл, то при загрузке он блокирует сервер для любых других запросов. Есть ли способ, которым я могу разместить файл, когда PHP продолжает отвечать на запросы?
Мне нужен PHP, чтобы убедиться, что пользователю разрешено загружать файл с их учетными данными, поэтому я не могу просто разместить его в качестве актива. Файл находится на FTP-сервере.
function download($file) { $fileStream = ""; if($this->get($file)) { //Send header to browser to receive a file header("Content-disposition: attachment; filename=\"$file\""); header("Content-type: application/octet-stream"); header("Pragma: "); header("Cache-Control: no-cache"); header("Expires: 0"); $data = readfile($this->downloadDir . $file); $i=0; while ($data[$i] != "") { $fileStream .= $data[$i]; $i++; } unlink($this->downloadDir . $file); echo $fileStream; exit; } else { return false; } }
PHP не является лучшим решением для такого рода работ, но он может делегировать задание веб-серверу, который вы используете. И поскольку файл находится в том же месте, что и ваше приложение, это может сработать.
Все основные веб-серверы, которые обычно запускают приложения PHP ( Apache , lighttpd и nginx ), имеют всю поддержку XSendfile
.
Чтобы использовать его, вы должны сначала включить функции на своем веб-сервере (проверьте ссылки выше для каждого из веб-серверов), затем в вашем скрипте добавьте новый заголовок:
Apache:
header("X-Sendfile: $location_of_file_to_download");
Lighttpd:
header("X-LIGHTTPD-send-file: $location_of_file_to_download");
Nginx:
header("X-Accel-Redirect: $location_of_file_to_download");
Веб-сервер поймает этот заголовок из вашего приложения и заменит тело вашего ответа PHP файлом. И пока он загружает этот файл пользователю, PHP разблокируется и готов к серверу нового пользователя.
(Остальные заголовки будут сохранены, поэтому вы можете сохранить заголовки содержимого и содержимого)
Поскольку PHP однопоточен, вам нужно будет создать структуру для каждого запроса. Затем вместо того, чтобы обрабатывать только один запрос за раз, вы должны прокручивать структуры и медленно обрабатывать их одновременно (как при отправке нескольких сотен килобайт в один, затем переходить на следующий и т. Д.).
Честно говоря, PHP не похож на правильный язык для выполнения этой работы. Почему бы не использовать специально созданный FTP-сервер, например, vsftp или что-то в этом роде?