PHP, отображать изображение с заголовком ()

Я показываю изображения из-за пределов своего веб-корня, например:

header('Content-type:image/png');
readfile($fullpath);

Content-type: image / png - вот что меня смущает.

Кто-то еще помог мне с этим кодом, но я заметил, что не все изображения в формате PNG. Многие из них jpg или gif.
И все же они успешно отображаются.

кто-нибудь знает почему?


person coffeemonitor    schedule 13.04.2010    source источник


Ответы (6)


Лучшим решением было бы прочитать файл, затем решить, что это за изображение, и отправить соответствующий заголовок.

$filename = basename($file);
$file_extension = strtolower(substr(strrchr($filename,"."),1));

switch( $file_extension ) {
    case "gif": $ctype="image/gif"; break;
    case "png": $ctype="image/png"; break;
    case "jpeg":
    case "jpg": $ctype="image/jpeg"; break;
    case "svg": $ctype="image/svg+xml"; break;
    default:
}

header('Content-type: ' . $ctype);

(Примечание: правильный тип содержимого для файлов JPG - image/jpeg)

person paullb    schedule 14.04.2010
comment
Я ценю пример кода для получения расширения. Конкретность - определенно лучшая практика. - person coffeemonitor; 14.04.2010
comment
Вместо использования substr и strrchr вы можете просто использовать pathinfo ($ filename, PATHINFO_EXTENSION). Легче читать. - person Gabriel; 08.01.2014
comment
это предполагает, что файл изображения имеет правильное расширение. - person ina; 13.09.2014
comment
Кстати, я обнаружил, что указание image / jpeg работает для отображения любого типа изображения в любом текущем браузере. Я не пробовал это с загрузкой изображений. - person Ixalmida; 07.11.2014
comment
Я бы включил перерыв по умолчанию только для единообразия, но переключатель падения делает его очень четким ответом. - person Louis Loudog Trottier; 08.12.2016
comment
вы также можете рассмотреть возможность использования mime_content_type ($ filename) для более общих целей. - person simongcc; 12.04.2019
comment
Для svg добавьте эту строку case "svg": $ctype="image/svg+xml"; break;. - person Jens Törnell; 31.05.2019

Зачем лучше определять тип изображения. с exif_imagetype

Если вы используете эту функцию, вы можете определить реальное расширение изображения.

с этой функцией расширение имени файла совершенно не имеет значения, и это хорошо.

function setHeaderContentType(string $filePath): void
{
    $numberToContentTypeMap = [
        '1' => 'image/gif',
        '2' => 'image/jpeg',
        '3' => 'image/png',
        '6' => 'image/bmp',
        '17' => 'image/ico'
    ];

    $contentType = $numberToContentTypeMap[exif_imagetype($filePath)] ?? null;
    
    if ($contentType === null) {
        throw new Exception('Unable to determine content type of file.');
    }

    header("Content-type: $contentType");
}

Вы можете добавить больше типов по ссылке.

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

person aliqandil    schedule 07.03.2014

Браузеры делают наилучшие предположения на основе полученных данных. Это работает для разметки (что веб-сайты часто ошибаются) и другого медиа-контента. Программа, которая получает файл, часто может выяснить, что он получил, независимо от типа содержимого MIME, о котором ей сообщили.

Однако вы не должны полагаться на это. Рекомендуется всегда использовать правильный MIME-контент.

person cletus    schedule 13.04.2010

Браузеры часто могут определить тип изображения, считывая метаинформацию изображения. Кроме того, в этом заголовке должен быть пробел:

header('Content-type: image/png');
person karim79    schedule 13.04.2010

Несмотря на странное название, вы можете использовать функцию getimagesize(). Это также даст вам информацию о пантомиме:

Array
(
    [0] => 295 // width
    [1] => 295 // height
    [2] => 3 // http://php.net/manual/en/image.constants.php
    [3] => width="295" height="295" // width and height as attr's
    [bits] => 8
    [mime] => image/png
)
person Martijn    schedule 28.12.2016

если вы знаете имя файла, но не знаете его расширение, вы можете использовать эту функцию:

public function showImage($name)
    {

         $types = [
             'gif'=> 'image/gif',
             'png'=> 'image/png',
             'jpeg'=> 'image/jpeg',
             'jpg'=> 'image/jpeg',
         ];
         $root_path  = '/var/www/my_app'; //use your framework to get this properly ..
         foreach($types as $type=>$meta){
             if(file_exists($root_path .'/uploads/'.$name  .'.'. $type)){
                 header('Content-type: ' . $meta);
                 readfile($root_path .'/uploads/'.$name .'.'. $type);
                 return;
             }
         }
    }

Примечание. Правильный тип содержимого для файлов JPG - image/jpeg.

person d.raev    schedule 18.02.2015