Как мне найти mime-тип файла с php?


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

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

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

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

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

Author: j0k, 2008-09-25

13 answers

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

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

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

 49
Author: leek, 2014-02-26 04:46:14

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

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

$file = escapeshellarg( $filename );
$mime = shell_exec("file -bi " . $file);
$filename should probably include the absolute path.
 22
Author: Eric_WVGG, 2012-02-14 13:53:10
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 запрещено.

 17
Author: Ale, 2012-11-26 04:46:01

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

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

Вот класс Mimereader.

require_once("MimeReader.php");

$mime = new MimeReader(<YOUR FILE PATH>);
$mime_type_string = $mime->getType();     // "image/jpeg" etc.
 10
Author: Shane, 2016-09-09 02:59:29

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

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

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

 8
Author: Andrew, 2013-03-06 19:52:28

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

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

 1
Author: Devon, 2008-09-25 18:01:38

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

 1
Author: David, 2016-01-31 05:20:22

Вы можете использовать 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 и кодировку, если они доступны (например, изображение/png; кодировка=двоичная или текстовая/x-php; кодировка=us-ascii). Смотрите этот сайт для получения дополнительной информации.

 1
Author: jhaagsma, 2016-10-12 17:34:25

Я не использовал его, но есть расширение PECL для получения миметического типа файла. Официальная документация для этого находится в руководстве.

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

 0
Author: enobrev, 2008-09-25 18:00:47

Я получил очень хорошие результаты, используя пользовательскую функцию из http://php.net/manual/de/function.mime-content-type.php @"джон дот Говард в prismmg dot com 26 октября-2009 03:43"

function get_mime_type($filename, $mimePath = '../etc') { ...

Который не использует finfo, exec или устаревшую функцию

Также хорошо работает с удаленными ресурсами!

 0
Author: vizzy, 2012-09-12 11:59:28

Если вы имеете дело только с изображениями, вы можете использовать функцию [getimagesize()][1], которая содержит всевозможную информацию об изображении, включая тип.

Более общий подход заключался бы в использовании расширения FileInfo из PECL. Документацию PHP для этого расширения можно найти по адресу: http://us.php.net/manual/en/ref.fileinfo.php

У некоторых людей есть серьезные жалобы на это расширение... поэтому, если вы столкнетесь с серьезными проблемами или по какой-то причине не сможете установить расширение возможно, вы захотите проверить устаревшую функцию mime_content_type()

 0
Author: phatduckk, 2014-05-22 13:20:25

Если вы используете 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;
}
 0
Author: techouse, 2016-08-24 18:58:38

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

<?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
Author: Joshua, 2017-11-28 01:02:59