Intereting Posts
PHP, получение переменной из другого php-файла Используйте два разных шрифта в imagemagick на одной строке Использование значения столбца как индекса массива в доктрине Существуют ли какие-либо проекты для PHP, похожие на ActiveMerchant для Ruby? Почему этот код для центрирования текста в PDF-формате с использованием библиотеки PHP Zend_Pdf не работает? Как обнаружить сломанное изображение и заменить его другим? $ _FILE upload large file дает ошибку 1, хотя upload_max_size больше размера файла Хранить MySQL в массиве PHP для двух запросов PHP: самый простой способ получить дату месяца за 6 месяцев до первого? Объект PHP ориентирован или нет? Доступ запрещен для пользователя при попытке соединения с PDO Laravel 5 UnexpectedValueException в ответ на запрос из-за использования данных POINT Уязвимое расширение Doctrine 'on change' не работает Как игнорировать случай при анализе с помощью simplexml? Как настроить сообщения об ошибках регулярного выражения Zend_Form?

Как вернуть изображение в запрос https с помощью PHP

После многих часов,

Я прибил мою проблему относительно загрузки изображения с помощью запроса https. Когда я получаю доступ к изображению с жестким путем (https://mysite/tmp/file.jpg) , apache возвращает его с успехом, и я могу просматривать его в браузере без каких-либо дополнительных манипуляций. Когда я пытаюсь получить к нему доступ с другим путем (https://mysite/files/file.jpg) , чтобы контролировать его доступ с помощью php, я получаю ответ от моего php-кода, но я не могу просмотреть изображение в браузере ,

  • Определен VirtualHost; mysite: установить в / var / www / mysite
  • $ Приложение [ 'контролеры'] -> requireHttps ();

Описание среды:

 mysite/tmp/file.jpg mysite/files/.htaccess //... no files; handled by Silex router. here is the .htaccess: --- <IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^ ../web/index.php [L] </IfModule> --- 
  • https: // mysite / tmp / file.jpg, обслуживается с https: 200 и просматривается в браузере; ОК
  • https: // mysite / files / file.jpg подается с https: 200, но не просматривается в браузере; ?

Вот три метода:

Метод 1: Silex sendFile () прямой метод>

 $app->get('/files/{onefile}', function ($onefile) use ($app) { // Validate authorization; if ok, then return $app->sendFile('/var/www/mysite/tmp/' . $onefile); }); 

Способ 2: потоковая передача Silex>

 $app->get('/files/{onefile}', function ($onefile) use ($app) { // Validate authorization; if ok, then $stream = function () use ($file) { readfile($file); }; return $app->stream($stream, 200, array('Content-Type' => 'image/jpeg')); 

Способ 3: стиль Symfony2>

 $app->get('/files/{onefile}', function ($onefile) use ($app) { // Validate authorization; if ok, then $exactFile="/var/www/mysite/tmp/" . $onefile; $response = new StreamedResponse(); $response->setCallback(function () use ($exactFile) { $fp = fopen($exactFile, 'rb'); fpassthru($fp); }); $response->headers->set('Content-Type', 'image/jpg'); $response->headers->set('Content-length', filesize($exactFile)); $response->headers->set('Connection', 'Keep-Alive'); $response->headers->set('Accept-Ranges','bytes'); $response->send(); 

Это то, что Chrome представляет:

введите описание изображения здесь

С этим изображением Chrome это запрос Http (Https или нет, тот же результат)

 Request URL:https://mysite/files/tmpphp0XkXn9.jpg Request Method:GET Status Code:200 OK Request Headers: Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Encoding:gzip,deflate,sdch Accept-Language:en-US,en;q=0.8 Cache-Control:no-cache Connection:keep-alive Cookie:XDEBUG_SESSION=netbeans-xdebug; _MYCOOKIE=u1k1vafhaqik2d4jknko3c94j1 Host:mysite Pragma:no-cache User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36 Response Headers: Accept-Ranges:bytes Cache-Control:no-cache Connection:Keep-Alive, Keep-Alive Content-Length:39497 Content-Type:image/jpg Date:Thu, 13 Jun 2013 13:44:55 GMT Keep-Alive:timeout=15, max=99 Server:Apache/2.2.16 (Debian) X-Powered-By:PHP/5.3.3-7+squeeze15 

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

  • Я проверил спецификацию и убедился, что php-код, отвечающий запросу, действителен и не имеет нежелательных меток байтов (спецификаций) с использованием Emacs ( set-buffer-file-coding-system utf-8 ). Кроме того, чтобы избежать неизвестных файлов с помеченными тегами, я выполнил следующую команду в каталоге mysite ( grep -rl $'\xEF\xBB\xBF' . ). Ничего необычного не появилось.

ОБНОВИТЬ:

Если посмотреть на файлы (изображения), полученные браузером ( save as на каждом изображении), это то, что помогает мне инструмент (Hex Friend), но я до сих пор не понимаю, почему:

Сравнение двух файлов

  • (один с успехом: mysite / tmp / file.jpg; обслуживается непосредственно Apache )
  • (один без успеха: mysite / files / file.jpg; обслуживается скриптом PHP ).

В начале двоичного файла я получаю эту разницу: введите описание изображения здесь

В конце двоичного файла я получаю эту разницу: введите описание изображения здесь

Вопрос: Как я могу вернуть изображение (по потоку или какой-либо другой технике) с помощью php-кода и просмотреть его в браузере? Все методы PHP-кода возвращают один и тот же результат, я подозреваю, что проблема с окружением. Есть ли настройка среды, которая может вызвать ошибку, которую я экспериментирую?

Я не доволен этим решением (A PATCH ), но проблема исправлена, добавив следующий вызов:

 $app->get('/files/{onefile}', function ($onefile) use ($app) { ob_end_clean(); // ob_clean() gave me the same result. ... } 

Хорошо, это исправлено, но может ли кто-нибудь объяснить мне, как исправить это более разумно?

ОБНОВИТЬ

Что случилось ?:

Это то, что моя интерпретация:
Дополнительные строки новой строки остаются в исходных файлах orignal php для непреднамеренной позиции! Оказывается, когда у вас есть php-файл

 <?php ... ?> 

где вы оставили некоторые новые строки (или пробелы) после ?> , эти новые строки будут добавлены в выходной буфер. Затем, пытаясь передать поток на выходной файл, они будут складывать новые строки и помещать их туда, где они принадлежат: в потоке заголовка или в потоке нижнего колонтитула. Наличие фиксированного размера для потока (равного размеру изображения) будет принимать специально дополнительные символы заголовка и соответственно сдвигать байты, выводимые в браузер. Я подозревал, что я добавляю ровно 5 символов ( 0A 0A 20 0A 0A ), соответствующих ( linefeed linefeed space linefeed linefeed ), обнаруженной в полученном изображении из браузера. Теперь браузер не распознает структуру изображения, будучи сдвигом со смещения 0, из 5 не логических символов для двоичного изображения. Поэтому браузер может показывать только сломанное изображение.

Также посмотрите: Еще одна помощь SO fix

Посоветуйте разработчику фреймворка PHP:

Если вы предоставляете эквивалентный метод sendFile() , возможно, вы должны выбросить Exception , когда ob_get_contents() не возвращает пустой буфер, перед потоковой передачей на вывод!

На данный момент:

Этот небольшой пакетный файл Linux может по крайней мере позволить вам найти, где ваш код должен быть очищен. После использования я смог удалить ob_end_clean() … после анализа вывода этого маленького скрипта. Он сообщает вам подозрительные php-файлы, которые могут содержать дополнительное пространство или новую строку в конце ваших php-файлов. Просто выполните и вручную исправьте файлы:

 #!/bin/bash for phpfiles in $(ls -1R *.php); do hexdump -e '1/1 "%.2x"' $phpfiles | tail -1 >endofphpfile; if [ `cat endofphpfile` = "3f3e" ]; then echo "OK.................File $phpfiles" else thisout=`cat endofphpfile` echo "File $phpfiles: Suspucious. Check ($thisout) at the EOF; it should end with '?>' (in hex 3f3e) " fi done 

Это, безусловно, может быть улучшено, но это должно, по крайней мере, помочь кому угодно!

не используйте закрытие ?> … это против стандартов кодирования Symfony.

Против PSR-2 будет более конкретным.

Все файлы PHP ДОЛЖНЫ заканчиваться пустой пустой строкой.

Закрывающий?> Тег ДОЛЖЕН быть опущен из файлов, содержащих только PHP.

Причина этого частично в том, что вы испытали.

Такое поведение иногда вызывает и спецификация .

проверьте, что ни один из ваших файлов не содержит байтовую марку!