Как мне найти mime-тип файла с php? - PullRequest
48 голосов
/ 25 сентября 2008

Хорошо, у меня есть файл index.php, который должен обрабатывать много разных типов файлов. как мне угадать тип файла на основе REQUEST_URI.

Если я запрашиваю http://site/image.jpg, и все запросы перенаправляются через index.php, который выглядит следующим образом

<?php
   include('/www/site'.$_SERVER['REQUEST_URI']);
?>

Как бы мне заставить это работать правильно?

Должен ли я проводить тестирование на основе расширения запрашиваемого файла или есть способ получить тип файла?

Ответы [ 13 ]

49 голосов
/ 25 сентября 2008

Если вы уверены, что когда-либо работаете только с изображениями, вы можете проверить getimagesize () exif_imagetype () PHP-функцию, которая пытается вернуть изображение mime-типа.

Если вы не возражаете против внешних зависимостей, вы также можете проверить превосходную библиотеку getID3 , которая может определять mime-тип для множества различных типов файлов.

Наконец, вы можете проверить функцию mime_content_type () , но она устарела для расширения Fileinfo PECL.

22 голосов
/ 25 сентября 2008

mime_content_type () устарела, поэтому вы не сможете рассчитывать на его работу в будущем. Существует расширение PECL "fileinfo", но я не слышал об этом ничего хорошего.

Если вы работаете на * nix сервере, вы можете сделать следующее, что отлично сработало для меня:

$file = escapeshellarg( $filename );
$mime = shell_exec("file -bi " . $file);
$filename should probably include the absolute path.
18 голосов
/ 30 августа 2012
function get_mime($file) {
  if (function_exists("finfo_file")) {
    $finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
    $mime = finfo_file($finfo, $file);
    finfo_close($finfo);
    return $mime;
  } else if (function_exists("mime_content_type")) {
    return mime_content_type($file);
  } else if (!stristr(ini_get("disable_functions"), "shell_exec")) {
    // http://stackoverflow.com/a/134930/1593459
    $file = escapeshellarg($file);
    $mime = shell_exec("file -bi " . $file);
    return $mime;
  } else {
    return false;
  }
}

Для меня ничего из этого не работает - mime_content_type устарело, finfo не установлено и shell_exec не разрешено.

10 голосов
/ 01 августа 2013

Мне на самом деле надоело отсутствие стандартных методов анализа MIME в PHP. Установите fileinfo ... Используйте устаревшие функции ... Ох, эти работы, но только для изображений! Я сыт по горло этим, поэтому я провел некоторое исследование и нашел WHATWG Mimesniffing spec - я думаю, что это все еще черновая спецификация, хотя.

В любом случае, используя эту спецификацию, я смог реализовать mimesniffer в PHP. Производительность не проблема. Фактически на моем скромном компьютере я смог открыть и прослушать тысячи файлов до истечения времени ожидания PHP.

Вот класс MimeReader .

require_once("MimeReader.php");

$mime = new MimeReader(<YOUR FILE PATH>);
$mime_type_string = $mime->getType();     // "image/jpeg" etc.
8 голосов
/ 06 марта 2013

Если вы работаете только с изображениями и вам нужен тип mime (например, для заголовков), то это самый быстрый и прямой ответ:

$file = 'path/to/image.jpg';
$image_mime = image_type_to_mime_type(exif_imagetype($file));

Он выведет истинный тип пантомимы изображения, даже если вы переименуете свой файл изображения

1 голос
/ 12 октября 2016

Вы можете использовать finfo для достижения этого начиная с PHP 5.3:

<?php
$info = new finfo(FILEINFO_MIME_TYPE);
echo $info->file('myImage.jpg');
// prints "image/jpeg"

Флаг FILEINFO_MIME_TYPE является необязательным; без него вы получите более подробную строку для некоторых файлов; (по-видимому, некоторые типы изображений будут возвращать информацию о размере и глубине цвета). Использование флага FILEINFO_MIME возвращает тип mime и кодировку, если она доступна (например, image / png; charset = binary или text / x-php; charset = us-ascii). См. этот сайт для получения дополнительной информации.

1 голос
/ 31 января 2016

mime_content_type(), кажется, путь, несмотря на вышеупомянутые комментарии, говорящие, что это устарело. Это не так - или, по крайней мере, это воплощение mime_content_type() не считается устаревшим, согласно http://php.net/manual/en/function.mime-content-type.php. Это часть расширения FileInfo, но документация PHP теперь говорит нам, что он включен по умолчанию с PHP 5.3 +0,0.

1 голос
/ 25 сентября 2008

Согласно руководству по php, функция finfo-file - лучший способ сделать это. Однако вам нужно будет установить расширение FileInfo PECL.

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

0 голосов
/ 28 ноября 2017

Мим любого файла на вашем сервере можно получить с помощью этого

<?php
function get_mime($file_path){
  $finfo = new finfo(FILEINFO_MIME_TYPE);
  $type  = $finfo->file(file_path);
}

$mime = get_mime('path/to/file.ext');
0 голосов
/ 24 августа 2016

Если вы работаете в Linux и у вас есть расширение, вы можете просто прочитать тип MIME из /etc/mime.types, создав массив хешей. Затем вы можете сохранить это в памяти и просто вызвать MIME по ключу массива:)

/**
 * Helper function to extract all mime types from the default Linux /etc/mime.types
 */
function get_mime_types() {
    $mime_types = array();
    if (
        file_exists('/etc/mime.types') &&
        ($fh = fopen('/etc/mime.types', 'r')) !== false
    ) {
        while (($line = fgets($fh)) !== false) {
            if (!trim($line) || substr($line, 0, 1) === '#') continue;
            $mime_type = preg_split('/\t+/', rtrim($line));
            if (
                is_array($mime_type) &&
                isset($mime_type[0]) && $mime_type[0] &&
                isset($mime_type[1]) && $mime_type[1]
            ) {
                foreach (explode(' ', $mime_type[1]) as $ext) {
                    $mime_types[$ext] = $mime_type[0];
                }
            }
        }
        fclose($fh);
    }
    return $mime_types;
}
...