Загрузка больших файлов с помощью PHP с помощью mod_xsendfile в Linux

Мне нужно было обслуживать очень большие файлы (1 Гб +) с моего веб-сервера, используя PHP и аутентификация, чтобы только некоторые клиенты имели права на скачивание файлов.

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

Мой веб-сервер управляется с Plesk и работает на Apache / CentOS 6.

2

Решение

Выбранное решение состояло в том, чтобы установить mod_xsendfile на сервере Centos, настроить его и отправить файлы с заголовками PHP после аутентификации пользователя.

Установка mod_xsendfile на Centos. Вам нужно включить репозиторий EPEL, чтобы получить xsendfile, после этого просто:

yum update
yum install mod_xsendfile

После этого вы можете проверить, правильно ли установлен модуль, используя:

apachectl -M | grep xsendfile

Конфигурация / Plesk часть. Plesk генерирует каждый файл httpd.conf автоматически, поэтому изменение файлов вручную опасно, поскольку они могут быть перезаписаны любым изменением, выполненным через пользовательский интерфейс Plesk. По умолчанию файл http.conf включает vhost.conf и vhost_ssl.conf, для виртуальных хостов они хранятся в

/var/www/vhosts/system/[yourvhostname]/conf

Вы можете редактировать их через ssh или через интерфейс пользовательского интерфейса Plesk (vhost -> настройки сервера -> дополнительные директивы apache). Для пользователей, не являющихся пользователями Plesk, просто добавьте следующие директивы в правильный раздел vhost вашего httpd.conf

В первый раз у меня были некоторые проблемы, потому что сервер отправлял файлы размером 0 байт, после некоторого теста я нашел правильные директивы:

<Directory "/">

EnableSendfile on

XSendFile on

# Absolute path, no trailing slash!
XSendFilePath "/var/www/vhosts/[yourvhostname]/storage"
</Directory>

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

Потому что я использую Laravel в качестве PHP-фреймворка, затем файл можно отправить пользователю с помощью:

   return response(null)
->header('Content-Type' , 'application/octet-stream')
->header('Content-Disposition', 'attachment; '.$filename)
->header('X-Sendfile', $fullfilepath);

Надеюсь, это поможет кому-то избежать многочасовых испытаний.

4

Другие решения

Комментарий Дарио выше действительно полезен. Я просто хотел добавить то, что использовал для оператора возврата Laravel, чтобы убедиться, что файлы имеют правильные имена:

return response(null)
->header('Content-Type' , 'application/octet-stream')
->header('Content-Disposition', 'attachment; filename="' . $filename . "')
->header('X-Sendfile', $fullfilepath);
2

По вопросам рекламы [email protected]