symfony2 сохранить загруженный файл без rootweb

У меня проблема с загрузкой файлов, я сохраняю загруженные файлы в непубличной папке (не в папке webroot), а затем хочу получить webPAth всех загруженных файлов, чтобы использовать их в видеогалерее.

$videos = $repository->getVideosThumbs($this->getUser());

а потом в моей ветке

{% for video in videos %}
         <a href ="{{ path('neoctus_videobundle_default_watchvideo', {'id' : video.id, 'salt' : app.user.salt }) }}" >
            <img id="{{ video.id }}" src="/uploads/images/{{video.imgPath}}" alt="1st image description" height="150" width="150"  />
         </a>
    {% endfor %}

но я не могу получить доступ к изображениям, потому что папка не является общедоступной, я знаю, что должен пройти через x-sendFile, но я не вижу, как я могу отправить несколько файлов JPEG в заголовке, а затем, как восстановить после ветки.

2 ответа

Решение

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

Смотрите пример на http://php.net/manual/en/function.readfile.php

Вам нужно будет изменить

header('Content-Disposition: attachment; filename='.basename($file));

в

header('Content-Disposition: inline; filename='.basename($file));

ОБНОВИТЬ:

Если у вас есть действие контроллера, которое будет передавать запрашиваемый файл в потоковом режиме, вы можете отобразить его в TWIG, запросив это действие с требуемым идентификатором файла:

<img src="{{ path('route_to_stream_action', {'fileId':'some_id'}) }}">

Браузер будет обрабатывать потоковый файл так же, как если бы к нему обращались напрямую, поэтому к нему можно применить любой CSS.

ОБНОВИТЬ:

Пример действия контроллера:

public function streamFileAction($fileId)
{

    // implement your own logic to retrieve file using $fileId
    $file = $this->getFile($fileId);

    $filename = basename($file);

    $response = new StreamedResponse();
    $response->setCallback(function () use ($file){
        $handle = fopen($file->getRealPath(), 'rb');
        while (!feof($handle)) {
            $buffer = fread($handle, 1024);
            echo $buffer;
            flush();
        }
        fclose($handle);
    });
    $d = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_INLINE, $filename);
    $response->headers->set('Content-Disposition', $d);
    $response->headers->set('Content-Type', $file->getMimeType());

    return $response;
}

Вы также можете использовать функцию "контроллер" в ветке:

{{ render(controller('AcmeBundle:Controller:action')) }}

запустит

actionAction в ControllerController в AcmeBundle.

Надеюсь, это поможет как-то.

Другие вопросы по тегам