2015-12-15 2 views
0

Я хотел был бы загрузить мой собственный чувствительный файл от службы с Symfony. Я немного смущен всем материалом, содержащимся в документации Symfony. По умолчанию я могу получить доступ только к файлу, размещенному в папке /web.Сервисный файл из безопасного места с Symfony

Но если я прав, эта папка является общедоступной. Поэтому я хочу переместить файл на /src/AppBundle/Resources/myfile.txt

Вот несколько ссылок, которые я прочитал, не нахожу ничего понятного.

Должен ли я использовать __DIR__ заявление?

Я 2 цели достичь, если это возможно:

  • доступа к файлу с относительным путем к проекту (например, AppBundle или «WWW» папка)
  • Доступ к файлам в /random/place/on/my/server без воздействия на цельном путь.

Последнее добавление; Невозможно скопировать мои файлы в веб-папку, для доступа к ним доступно более 10 ГБ файлов, поэтому нет кеша, нет копии, просто прокси.

ответ

7

Вы можете служить файл в Symfony, используя следующий код:

$response = new BinaryFileResponse($filepath); 

    // Set headers 
    $response->headers->set('Cache-Control', 'private'); 
    $response->headers->set('Content-Type', $file->getMimeType()); 
    $response->headers->set('Content-Disposition', $response->headers->makeDisposition(
     ResponseHeaderBag::DISPOSITION_ATTACHMENT, 
     $file->getName() 
    )); 

    return $response; 

Убедитесь, что у вас также есть:

use Symfony\Component\HttpFoundation\ResponseHeaderBag; 
use Symfony\Component\HttpFoundation\BinaryFileResponse; 

Как получить $file объясняется в документации из Finder component вы» связанный. Когда вы кладете код в контроллере в AppBundle вы можете использовать:

$filepath = __DIR__ . '/../Resources/myfile.txt'; 

Или вы можете использовать путь относительно корневого приложения:

$rootDir = $this->get('kernel')->getRootDir(); 
$filepath = $rootDir. '/src/AppBundle/Resources/myfile.txt'; 

$filepath может быть абсолютным путем, как хорошо, но убедитесь, что веб-сервер может читать с этого пути. Пока вы используете путь вне webservers docroot (который, вероятно, <your app root>/web), вы можете управлять доступом к файлу с помощью избирателей и другой пользовательской логики в PHP.

Получение $ файла объекта:

Для того, чтобы построить свой объект файла вы можете использовать компонент Finder, но это на самом деле ничего более, что обертка вокруг SPL filehandling.Можно поэтому использовать:

$file = new \SplFileInfo($filepath); 

Почему BinaryFileResponse?

При отправке больших файлов PHP может прочитать весь файл в памяти перед отправкой его в качестве ответа клиенту. Это может привести к тому, что у PHP закончится нехватка памяти. Использование BinaryFileResponse позволяет избежать этого, прочитав файл поблочно и потоковой передачи этих блоков клиенту. Поэтому никогда не отправляйте большие файлы с помощью объекта Response.

Использование X-SendFile:

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

Luckely, вместо этого:

Request ----> Webserver ----> PHP-FPM ----> File 
Response <--- Webserver <---- PHP-FPM <---- File 

Вы можете сделать это:

Request ----> Webserver ----> PHP-FPM 
Response <--- Webserver <---- PHP-FPM 
       ^| 
       | | 
       | V 
       File 

Это делается с помощью X-Sendfile.

Это нечестиво, как я могу это использовать?

Получение для работы требуется два простых шага:

  1. Добавление заголовка в своем ответе, что говорит ваш веб-сервер, что он должен сервер файл.
  2. Настройка вашего веб-сервера для чтения этого заголовка и на самом деле сервера этого файла.

Имя заголовка и, как ваш веб-сервер настроен, зависит от типа веб-сервера, который вы используете:

Заметим, что Nginx называет его X -Accel. Заголовок, который вы передаете Nginx, - X-Accel-Redirect, но это единственное отличие.

Смежные вопросы