Symfony2 принудительно загружает jpg, возвращает поврежденный файл

После некоторых из многих сообщений, связанных с этой темой, я наконец придумал эту версию кода «принудительной загрузки»:

public function downloadAction(Request $request){

    $filename= 'test.jpg';
    $response = new Response();

    $response->headers->set('Content-Type','image/jpg');
    $response->headers->set('Content-Disposition', 'attachment; filename="' . basename($filename) . '"');        

    $response->sendHeaders();
    $response->setContent(file_get_contents($filename)); 

    return $response;
} 

Теперь это прекрасно работает с zip-файлами (очевидно, с использованием правильного типа содержимого), но для jpg происходит нечто другое. При использовании HexCompare для проверки исходного и загруженного JPG я обнаружил, что загруженная версия добавляет «EF BB BF» в начале файла. Кажется, этого достаточно для средства просмотра изображений Windows, которое завершает сообщение об ошибке поврежденного файла.

С другой стороны, тот же загруженный jpg отлично открывается в Adobe Photoshop (может быть, менее строго?)

Идеи? любой?

Заранее спасибо.

Z

ОБНОВЛЕНИЕ: загруженные Zip-файлы с использованием этого кода можно открыть только с помощью WinRAR или WinZIP, извлечение Zip-файла проводника Windows показывает сообщение об ошибке Corrupt File Error.

ОБНОВЛЕНИЕ 2: Хорошо, теперь я знаю, что это проблема со спецификацией. Теперь, как я могу избавиться от этого неприятного «EF BB BF» из результата file_get_content?


person Zilos    schedule 23.05.2013    source источник


Ответы (1)


Попробуйте следующее, как предложено здесь

// Set headers
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', mime_content_type($filename));
$response->headers->set('Content-Disposition', 'attachment; filename="' . basename($filename) . '"');
$response->headers->set('Content-length', filesize($filename));

// Send headers before outputting anything
$response->sendHeaders();
$response->setContent(readfile($filename));

Если вы используете apache с mod_xsendfile, попробуйте:

return new Response('', 200, array(
    'X-Sendfile'          => $filename,
    'Content-type'        => 'application/octect-stream',
    'Content-Disposition' => sprintf('attachment; filename="%s"', $filename)),
     // ...
));    

Если вы используете X-Accel от nginx, прочитайте здесь. и использовать

return new Response('', 200, array(
    'X-Accel-Redirect'    => $filename,
    'Content-type'        => 'application/octect-stream',
    'Content-Disposition' => sprintf('attachment; filename="%s"', $filename)),
    // ...
));    

чтобы получить больше контроля с помощью nginx, доступны дополнительные параметры ...

// ...
'X-Accel-Limit-Rate' => '1024',
'X-Accel-Buffering'  => 'yes',  // yes|no
'X-Accel-Charset'    => 'utf-8',
 // ...
person Nicolai Fröhlich    schedule 23.05.2013
comment
Не работает нифр. Используя этот подход, загруженный файл становится на пару сотен КБ больше, но все еще поврежденным, даже для Photoshop. Файл, загруженный с исходным кодом, корректно открывается в Photoshop. - person Zilos; 23.05.2013
comment
Примечание. Исходный jpg-файл для тестирования имеет размер всего 633 КБ и отлично открывается в средстве просмотра изображений Windows 7. Проведено некоторое тестирование файла размером 11 КБ 1x1pix, тот же результат. - person Zilos; 23.05.2013
comment
На самом деле nifr, ЭТО был первый код, который я использовал. Взял именно из этого поста. Точно такой же результат. Продолжает добавлять EF BB BF в начале загруженного файла. ...сводит меня с ума. - person Zilos; 23.05.2013
comment
Вы пробовали xsendfile/x-accel? в любом случае это лучше, потому что файл напрямую обслуживается вашим веб-сервером. или это не вариант? Вы проверили свой код на наличие невидимых символов и правильную кодировку utf-8? - person Nicolai Fröhlich; 23.05.2013
comment
не вариант, и не могу достать апач. Кодировка UTF-8 правильная, то же самое для проверки непечатаемых символов. Продолжайте тестирование с другими форматами и размерами файлов, тот же результат. Отличие EF BB BF. Код не может быть проще, верно? - person Zilos; 23.05.2013
comment
Хорошо, теперь я знаю, что это проблема спецификации. Теперь, как я могу избавиться от этого неприятного EF BB BF из результата file_get_content? - person Zilos; 23.05.2013
comment
Вы проверили, что ни один из ваших php-файлов не является UTF-8 с спецификацией? - person Nicolai Fröhlich; 23.05.2013
comment
попробуйте sed -i '1 s/^\xef\xbb\xbf//' *.php, если вы используете Linux. какую операционную систему и какой IDE/редактор вы используете? - person Nicolai Fröhlich; 23.05.2013
comment
у вас есть cygwin для использования sed? в противном случае найдите другой способ убедиться, что в спецификации нет php-файла, и повторите попытку. очистите кеш после этого, пожалуйста. - person Nicolai Fröhlich; 23.05.2013
comment
thxs nifr, у меня его нет, но я скачаю и попробую. В любом случае, больше ничего не работает :) Только что случайно проверил некоторые файлы php без везения, нет спецификации. Проект Netbeans настроен на UTF-8, но я считаю, что это не связано со знаменитым фрагментом спецификации. Я имею в виду, что спецификация не определяет кодировку UTF-8, верно? и кодировка моего сайта должна быть UTF-8, в этом я уверен. Тогда мой вопрос: если после использования sed я не могу найти файлы PHP с заголовками BOM (мое предположение), то кто может помечать BOM полезную нагрузку ответа? апач? - person Zilos; 24.05.2013
comment
Apache может быть вариантом. вы уже проверили заголовки ответа? может там что-то не так. проверьте, все ли заголовки существуют. - person Nicolai Fröhlich; 24.05.2013
comment
повторение ответа показывает следующее: HTTP/1.0 200 OK Cache-Control: no-cache Content-Disposition: вложение; filename=test.jpg Тип содержимого: image/jpeg Дата: Чт, 23 мая 2013 г., 22:17:28 по Гринвичу ����NExifMM....и т.д., и т.д., и т.д... - person Zilos; 24.05.2013
comment
примечание: прямой вывод результата file_get_contents($filename) без заголовков также показывает фрагмент спецификации в начале файла: - person Zilos; 24.05.2013
comment
Поскольку вопрос больше не связан с решением, я решил начать новый, более конкретный, здесь: stackoverflow.com/questions/16737018 - person Zilos; 24.05.2013
comment
Хм, вы вполне можете принять мой ответ, поскольку он решает проблему, если пользователи используют расширения X-Accel или XSendfile (потому что тогда symfony больше не участвует в обслуживании заголовков файлов и выводе, я думаю) - person Nicolai Fröhlich; 24.05.2013