Как узнать mime type файла
В этом уроке мы рассмотрим различные стратегии получения MIME-типов файлов. Мы рассмотрим способы расширения типов MIME, доступных для стратегий, где это применимо.
Мы также покажем, где следует отдавать предпочтение одной стратегии перед другой.
2. Использование Java 7
Начнем с Java 7 – которая предоставляет метод Files.probeContentType(path) для разрешения типа MIME:
Этот метод использует установленные реализации FileTypeDetector для проверки типа MIME. Он вызывает probeContentType каждой реализации для разрешения типа.
Теперь, если файл распознается любой из реализаций, возвращается тип содержимого. Однако если этого не происходит, вызывается системный детектор типов файлов по умолчанию.
Однако реализации по умолчанию зависят от ОС и могут завершиться неудачей в зависимости от используемой ОС.
В дополнение к этому важно также отметить, что стратегия потерпит неудачу, если файл не будет присутствовать в файловой системе. Кроме того, если файл не имеет расширения, это приведет к сбою.
3. Использование URLConnection
3.1. Использование getContentType()
Мы можем использовать getContentType() метод URLConnection для получения MIME-типа файла:
Однако основным недостатком этого подхода является то, что он очень медленный .
3.2. Использование guessContentTypeFromName()
Далее давайте посмотрим, как мы можем использовать guessContentTypeFromName() для этой цели:
Этот метод использует внутреннюю карту FileName Map для разрешения типа MIME из расширения .
У нас также есть возможность использовать guessContentTypeFromStream() вместо этого, который использует первые несколько символов входного потока, чтобы определить тип.
3.3. Использование getFileNameMap()
Метод возвращает таблицу типов MIME, используемых всеми экземплярами URLConnection. Эта таблица затем используется для разрешения типа входного файла.
Встроенная таблица типов MIME очень ограничена, когда речь заходит о URLConnection .
4. Использование MimetypesFileTypeMap
MimetypesFileTypeMap разрешает типы MIME с помощью расширения файла. Этот класс поставляется с Java 6 и, следовательно, очень удобен при работе с JDK 1.6.
Теперь давайте посмотрим, как его использовать:
Здесь мы можем либо передать имя файла, либо сам экземпляр File в качестве параметра функции. Однако функция с File instance в качестве параметра внутренне вызывает перегруженный метод, который принимает имя файла в качестве параметра.
Внутренне этот метод ищет файл с именем Внутренне этот метод ищет файл с именем для разрешения типа. Очень важно отметить, что метод ищет файл в определенном порядке:
- Программно добавленные записи в экземпляр MimetypesFileTypeMap
- . mime.types в домашнем каталоге пользователя
- /lib/mime.types
- ресурсы с именем META-INF/mime.types
- ресурс с именем META-INF/mimetypes.default (обычно встречается только в activation.jar файл)
Однако, если файл не найден, он вернет application/octet-stream в качестве ответа.
5. Использование jMimeMagic
Давайте начнем с настройки зависимости Maven:
Мы можем найти последнюю версию этой библиотеки на Maven Central .
Далее мы рассмотрим, как работать с библиотекой:
Эта библиотека может работать с потоком данных и, следовательно, не требует присутствия файла в файловой системе.
6. Использование Apache Tika
Давайте начнем с настройки зависимости Maven:
Далее мы будем использовать метод detect() для разрешения типа:
Библиотека полагается на магические маркеры в префиксе потока для разрешения типа.
7. Заключение
В этой статье мы рассмотрели различные стратегии получения файла типа MIME. Кроме того, мы также проанализировали компромиссы подходов. Мы также указали сценарии, в которых мы должны отдавать предпочтение одной стратегии перед другой.
Полный исходный код , используемый в этой статье, доступен на GitHub , как всегда.
Медиа тип (так же известный как Multipurpose Internet Mail Extensions или MIME тип) является стандартом, который описывает природу и формат документа, файла или набора байтов. Он определён и стандартизирован в спецификации RFC 6838 .
Организация Internet Assigned Numbers Authority (IANA) является ответственной за все официально признанные MIME типы, и вы можете найти самый последний и полный лист MIME типов на их странице Медиа Типов.
Важно: Для принятия решения о том, как обрабатывать URL, браузеры используют MIME типы, а не расширения файлов, так что серверам необходимо отправлять правильные MIME типы в Content-Type заголовке ответа. При неточном задавании этого заголовка, браузеры с большой вероятностью будут неправильно интерпретировать и обрабатывать содержание файлов, из-за чего сайт будет работать неверно.
Структура MIME типа
Простейший MIME тип состоит из типа и подтипа — двух строк разделённых наклонной чертой ( / ), без использования пробелов.
Тип представляет общую категорию, в которой находится тип данных, например video или text . Подтип же строго отождествляется с отдельным типом данных, представляемых данным MIME типом. Например, для MIME типа text , подтипы могут быть plain (простой текст), html (HTML source code) или calendar (для iCalendar/ . ics ).
Необязательный параметр может быть добавлен для указания дополнительных деталей
Например, для MIME типов категории text , необязательный параметр charset может быть задан для уточнения кодировки, используемой в документе. Для объявления, что пересылаемый файл имеет кодировку UTF-8, необходимо использовать MIME тип text/plain;charset=UTF-8 . При не указании параметра charset , его значение автоматически будет задано, как ASCII ( US - ASCII ), если в настройках браузера не будет определено иначе.
MIME типы являются нечувствительными к регистру, но традиционно их пишут строчными буквами, за исключением значений параметров.
Дискретные типы
application Список IANA Любой вид бинарных данных, явно не попадающих ни в одну другу группу типов. Данные, которые будут выполняться или как-либо интерпретироваться, или данные для выполнения, которых необходимо отдельное приложение. Для указания базового типа бинарных данных (данных без определённого типа) используют тип application/octet-stream . Другие распространённые примеры включают application/pdf , application/pkcs8 и application/zip . audio Список IANA Аудио или музыкальные данные. Примеры: audio/mpeg , audio/vorbis . example Тип, зарезервированный для написания примеров, отображающих использование MIME типов. Этот тип никогда не должен использоваться вне примеров кода или документации. example может так же использоваться, как подтип. font Список IANA Данные шрифтов. Распространённые примеры включают font / woff , font / ttf и font / otf . image Список IANA Изображения или графические данные, включая векторную и растровую графику, а так же анимированные версии форматов неподвижных изображений, таких как GIF или APNG. Распространённые примеры включают image/ jpeg , image / png и image / svg + xml . model Список IANA Данные моделей для 3D объектов или сцен. Примеры: model/3mf и model/vml . text Список IANA Любые текстовые данные, так или иначе доступные для чтения человеку, а так же исходный код или текстовые данные для программ. Примеры: text / plain , text / csv и text / html . video Список IANA Видео данные или файлы. Например, MP4 фильмы ( video / mp 4 ).
Любые текстовые документы без определённого подтипа стоит отправлять, как text/plain тип. Аналогичным образом, application/octet-stream тип подойдёт бинарным документам при неопределённом или неизвестном подтипе.
Многокомпонентные типы
Существуют два многокомпонентных типа:
Важные для Web-разработчиков MIME типы
application/octet-stream
Этот тип является базовым для бинарных данных. В связи с тем, что он подразумевает неопределённые бинарные данные, браузеры, как правило, не будут пытаться его обработать каком-либо образом, а вызовут для него диалоговое окно «Сохранить Как», как если бы заголовок ответа Content-Disposition имел значение attachment .
text/plain
Этот тип является базовым для текстовых файлов. Несмотря на то, что он означает "неопределённые текстовые данные", браузеры всё равно могут его отображать.
Заметьте: text/plain не означает "любой вид текстовых данных". Если браузер ожидает получения какого-то конкретного типа текстовых данных, то с большой вероятностью он не будет считать text/plain подходящим типом. Например, при загрузке text/plain документа через <link> элемент, браузер не будет его признать правильным CSS файлом и использовать для применения стилей. Только text/css тип должен использоваться для загрузки CSS документов.
text/css
CSS документы, используемые для стилизации web-страниц должны отправляться, как text/css тип. Большинство браузеров не смогут распознавать CSS документы, загруженные с отличным от text/css MIME типом.
text/html
Все HTML данные должны пересылаться с данным типом. Альтернативные MIME типы для XHTML (например, application/xhtml+xml ) почти не используются в настоящее время.
Заметьте: Используйте application/xml или application/xhtml+xml , когда вам необходим строгий синтаксический анализ документов, разделы <![CDATA[…]]> или элементы, не принадлежащие к пространствам имён HTML/SVG/MathML.
text/javascript
Согласно HTML спецификации: при пересылке JavaScript файлов, всегда должен использоваться MIME тип text/javascript .
По исторически сложившимся причинам, MIME Sniffing Standard (стандарт, определяющий, как браузеры должны интерпретировать медиа типы и выяснять, как обрабатывать данные при неправильно заданных медиа типах) позволяет серверам отправлять JavaScript документы, используя один из нижеперечисленных типов:
- application/javascript
- application/ecmascript
- application/x-ecmascript
- application/x-javascript
- text/javascript
- text/ecmascript
- text/javascript1.0
- text/javascript1.1
- text/javascript1.2
- text/javascript1.3
- text/javascript1.4
- text/javascript1.5
- text/jscript
- text/livescript
- text/x-ecmascript
- text/x-javascript
Заметьте: Несмотря на то, что некоторые user agent могут поддерживать какие-то из вышеперечисленных типов, вы всегда должны использовать text / javascript . Это единственный MIME тип, который гарантированно будет работать в настоящее время и в будущем.
Иногда вы можете заметить использование text/javascript MIME типа в связке с параметром charset , для уточнения кодировки, в которой был написан файл. Такое определение MIME типа является неправильным, и в большинстве случаев браузеры не станут загружать скрипт, передаваемый с таким типом.
Типы изображений
Файлы, MIME типом которых является image , содержат в себе данные изображений. Подтип определяет, какой конкретный формат изображения представлен в данных.
Лишь несколько типов изображений достаточно распространены, чтобы безопасно использоваться на веб-страницах.
Аудио и видео типы
Так же как в случае с изображениями, стандарт HTML не обязывает браузеры поддерживать какие-либо определённые форматы и кодеки для <audio> и <video> элементов, так что при их выборе, важно брать в расчёт целевую аудиторию и диапазон браузеров (а так же версии этих браузеров), которые она может использовать.
Наше руководство по медиа форматам предоставляет список общепринятых типов, включая информацию об особых случаях при их использовании, их недостатках, совместимости, а так же других деталях.
Руководства по аудио и видео кодекам перечисляют часто поддерживаемые браузерами кодеки, предоставляя детали по их совместимости и техническую информацию, например как много аудио каналов они поддерживают, какой тип сжатия используют, и так далее. Руководство по используемым в WebRTC кодекам развивает эту тему ещё дальше, конкретно описывая кодеки, поддерживаемые популярными браузерами, так чтобы вы могли выбрать кодеки, которые имеют наилучшую поддержку в диапазоне браузеров по вашему выбору.
Что касается MIME типов для аудио и видео файлов, то чаще всего они указывают на формат контейнера (тип файла). Необязательный параметр codecs может быть добавлен к MIME типу для более точного указания, какой кодек и параметры использовались для пересылаемого файла.
Ниже перечислены наиболее часто используемые на веб-страницах MIME типы. Обратите внимание, что это не полный перечень всех доступных типов. Более полный список поддерживаемых форматов может быть наеден в руководстве по медиа форматам.
MIME тип | Аудио или видео тип |
---|---|
audio/wave audio/wav audio/x-wav audio/x-pn-wav | Аудио файл WAVE формата. С PCM аудио кодеком (WAVE кодек "1"), считающимся наиболее поддерживаемым, а так же другими, имеющими ограниченную поддержку. |
audio/webm | Аудио файл формата WebM. С Vorbis и Opus официально поддерживаемыми WebM спецификацией аудио кодеками. |
video/webm | Видео файл, с возможной аудио дорожкой, формата WebM. С VP8 и VP9, как наиболее распространёнными видео кодеками; Vorbis и Opus, как наиболее распространёнными аудио кодеками. |
audio/ogg | Аудио файл формата OGG. С Vorbis, как наиболее распространённым аудио кодеком. Хотя на данный момент имеется поддержка и Opus кодека. |
video/ogg | Видео файл, с возможной аудио дорожкой, в формате OGG. Где Theora – наиболее часто встречающийся видео кодек и Vorbis - наиболее часто встречающийся аудио кодек. Хотя использование кодека Opus становится всё более распространённым. |
application/ogg | Аудио или видео формата OGG. Где Theora – наиболее часто встречающийся видео кодек и Vorbis - наиболее часто встречающийся аудио кодек. |
multipart/form-data
multipart/form-data тип может быть использован при отправке значений из заполненной HTML Формы на сервер.
Следующая форма <form> :
multipart/byteranges
multipart/byteranges MIME тип используется для отправки данных в браузер по частям.
При отправке кода состояния 206 Partial Content , этот MIME тип будет означать, что документ состоит из нескольких частей, по одной для каждого отдельно запрашиваемого диапазона. Аналогично с остальными многокомпонентными типами, заголовок Content-Type используется для объявления границы boundary , разделяющей документ на отдельные компоненты. Каждый компонент имеет заголовок Content-Type , описывающий тип сегмента данных, и Content-Range (en-US), описывающий его диапазон.
Важность задания правильного MIME типа
Большинство серверов отправляет ресурсы неопределённого типа, как application/octet-stream MIME тип. Большинство же браузеров, в целях безопасности, не позволяет их никак обрабатывать, вынуждая пользователя сохранять их на жёсткий диск, для дальнейшего использования.
Несколько советов по правильной настройке MIME типов на серверах:
- RAR-сжатые файлы. В этом случае самым правильным вариантом было бы задать тип изначального ресурса; но это не всегда выполнимо, так как .RAR файлы могут хранить в себе несколько типов данных. Тогда, настройте сервер на отправку application/x-rar-compressed MIME типа вместе с RAR ресурсами.
- Аудио и видео. Только ресурсы с правильно заданными MIME типами могут производиться в <video> и <audio> элементах. Убедитесь, что вы используете правильные типы для аудио и видео данных.
- Запатентованные типы файлов. Избегайте использования application/octet-stream при их отправке, так как большинство браузеров не позволит определять способы обработки (например, "Открыть в Word") для этого базового MIME типа. Используйте специальные типы, например application/vnd.mspowerpoint , чтобы позволить пользователям открывать загруженный ресурс в программе по их выбору.
MIME sniffing
В отсутствии заданного MIME типа, или в определённых случаях, когда браузеры полагают, что MIME тип задан неправильно, они могут выполнять MIME sniffing — попытку угадать правильный MIME тип, анализируя характеристики ресурса.
Каждый браузер выполняет MIME sniffing по-своему и при разных условиях (например, Safari будет смотреть на расширение файла, если переданный MIME тип является неподходящим для документа). В этих случаях могут присутствовать опасения по поводу безопасности, так как некоторые MIME типы представляют исполняемые файлы. Сервера имеют возможность предотвращать MIME sniffing, отправляя X-Content-Type-Options заголовок ответа.
MIME (Multipurpose Internet Mail Extensions) — универсальные расширения для Интернет-почты. Используется для определения типа данных, формата файла, вида контента файла.
На самом деле он распространён не только в почте, но и во всем интернете, да и везде, где присутствует обработка файлов или работа с файлами. Например, операционные системы с графическими оболочками, где файлы отображаются не списком, а с иконками (предпросмотром), как в картинках, видео или PDF.
Введение
Если вы работали с ОС Windows (да если вы вообще работали с ПК или файлами), то замечали, что у каждого типа файла есть свое расширение. Например, у фотографий: jpeg, jpg, jpe, raw и т. д; у документов PDF (Portable Document Format) — pdf, а у установщиков (пакетов) приложений для Android — apk.
С закодированными файлами все понятно — в самом файле зашито расширение (тип MIME) файла, а вот с простыми текстовыми данными или распространёнными архивами дела обстоят иначе.
Рассмотрим типичные проблемы файла и содержимого.
Изменение расширения файла
В принципе это часть проблемы, которой я посвящаю статью и из-за чего вообще начал искать необходимые пакеты PHP для создания сайтов и для разработки системы управления, а вам возможно для разработки серверной части веб-приложения (в принципе как у меня).
Для продвинутых пользователей ПК известно, что изменив расширение файла (например, с png в jpg или 3gp в avi) внутренняя составляющая файла не изменится, т. е. не произойдёт чудо-конвертирования файла в новое расширение перекодировав все данные в новый формат (а было бы неплохо). Произойдет просто изменение имени файла.
Но, имя файла, особенно в ОС Windows, жёстко привязано к системе, но не спроста. Например, расширения в именах снижают количество обработок для ОС, а соответственно и увеличивают производительность. Представьте, что для определения типа файла и отображения его содержимого приходилось лезть в каждый файл, проверять его MIME, и только после этого проделывать остальные операции, такие как отображение миниатюры изображения, отображение типа файла по его содержимому (как это работает в Linux и происходит это не очень быстро, но 100% правильно, хотя могут быть и другие причины низких скоростей получения информации о файлах).
Изменение расширения файла могут приводить к ошибкам в программах используемых эти файлы, создания вредоносных файлов (такое часто делают) и просто путанице (это первая проблема).
Но в каждой операционной системе, программном обеспечении и т. п., могут быть разные способы обработки файла, что «имя файла» будет всего лишь именем и не будет иметь ничего общего с содержимым файла, потому что для определения содержимого файла, будет происходить чтение данных о файле из самого файла (внутренний заголовок файла). Это значит файл с именем «1» и файл «1.txt» на самом деле могут быть изображениями, но выяснится это, только после чтения этого заголовка.
Тип MIME не соответствует расширению файла
Вторая проблема типа MIME — существует множество типов файлов и расширений, которые всего лишь обёртки для системы, но не ПО работающими с ними.
По-русски: есть файл с расширением svg (векторная графика). Векторная графика представляется точками, функциями, значениями и т. п. и хранится в открытом виде, в виде обычного XML. Но к счастью, стандартная функция PHP mime_content_type определяет именно этот файл как надо и выдает значение «image/svg+xml», т. е. это SVG сохраненный в XML.
Капнем глубже и найдем нашу проблему. Возьмем файл пакета под Андроид с расширением apk. Что это за файл? Обычный архив. И вот тут, при считывании MIME в получаем значение «application/zip» вместо «application/vnd.android.package-archive». Самое интересное, что подобных форматов файлов достаточно много и это не единственное возвращаемое значение.
Выше была описана вторая проблема: расширение файла одно, содержимое — другое.
Скачивание файлов и их обработка
Еще две проблемы, точнее как следствия, которые вытекают из расширений и типов MIME.
При скачивании файла мы можем выдавать тип MIME скачеваемого файла. Это важно, когда у нас файл не соответствует своему названию. Хотя, чаще всего содержимое файла определяется из названия с указанным расширением.
Но название файла мы можем генерировать автоматически и тогда нам понадобиться хранить именно соответствующий тип (определяемый тип стандартными функциями PHP не соответствует действительности, а точнее соответствию MIME типов).
Следующая проблема — обработка файла по содержимому. Для серверов это задача важная, т. к. для обработки файла мы точно должны знать что внутри (особенно, когда форматов файлов много). Полученный тип MIME не соответствует необходимой обработке, остаётся полагаться только на расширение файла (но и оно может быть ложное, но об этом когда-нибудь позже).
Поэтому, я решил найти пакет, который решил бы мою проблему: по файлам будет определять их MIME, кроме этого, мне дополнительно нужна группа файла, которая также указывается в MIME, но во многих случаях она общая, т. е. «application», что значит файл открывается только со специализированным приложением (ПО), но мне нужно другое — определение групп image, document, video, archive и т. д. (две из перечисленных существует).
Обзор популярных пакетов PHP для получения MIME
В PHP существует стандартная функция для определения MIME-типа содержимого файла.
FileInfo
Это пакет, включаемый по умолчанию в PHP в версия 5.3, 7 и выше. До этого использовались другой способ определения типов данных: расширение Mimetype.
Как описано на сайте php, определение типа с помощью Mimetype определялось из файла соответствий (своего рода БД) подобному файлу поставляемому с Apache (файл magic ). Если мы заглянем в папку Апач, то увидим этот файл и его содержимое. Можно предположить, что считывание файла происходит на основе считанных первых байт содержимого файла и сопоставления с существующей таблицей. В соответствии с этой таблицей и определяется тип данных. Такой способ мы увидим дальше, а этот пакет был удален из PHP в пользу FileInfo.
Сначала рассмотрим упрощенную функцию mime_content_type.
string mime_content_type ( string $filename )
Возвращает MIME-тип содержимого файла, используя для определения информацию из файла magic.mime (как оказалось, он встроен уже в сам пакет).
В этом пакете есть и другие способы для определения типа файла — функция finfo_open с разными опциями. Но результат вывода будет соответственно такой же как и у функции mime_content_type.
Единственное отличие: мы можем указать свой магический файл с типами.
Из документации можно увидеть, что в PHP 7.2 появился новый параметр FILEINFO_EXTENSION. Как понятно из названия, он выводит список расширений файла (если их несколько) или знаки вопроса, когда тип неопределен.
К сожалению, используемая функция не дает нам нужного результата на версии PHP 7.0, но возможно что-то изменилось в версии 7.2.
Интересно: в системе Ubuntu (возможно и других Linux) есть пакеты для определения MIME типов: file и mimetype. Они выдают разный результат, и конечно же, все три используемых пакета выдают разный результат.
Результаты выводов функций для определения MIME-типов:
PHP 7.0 FileInfo (mime_content_type, finfo, file_open) при определения содержимого файла с Android-пакетом (файл «name.apk»): application/zip.
Результат меня вообще не устраивает. Такой же неподобаемый результат выдает при определении любых скриптов.
file --mime-type name.apk (пакет для Linux): application/java-archive.
Это также неподобаемый результат, т. к. на самом деле файлы с таким типом должны иметь расширение jar.
mimetype name.apk (пакет для Linux): application/vnd.android.package-archive.
Результат вывода этой команды меня полностью устроил. Но часть результатов на опробованных файлах все равно требует улучшения, хоть и не указываются стандартные выводы, типа «text/plain» или «application/zip».
Вывод: все пакеты хороши, но тут качество зависит только от заполненности базы (соответствий типов).
Пакет для PHP Mimey
Возможно неправильно сюда относить этот пакет, но он относительно хорош.
Mimey работает со значениями MIME и расширениями файлов. Он позволяляет «конвертировать» название MIME-типа в расширение и наоборот. Если у данного типа несколько расширений (как у JPEG), то можно вывести все, а можно только один.
Данный пакет работает только с названиями типов и расширениями, но не работает с файлами, т. е. вопрос о корректном определении все равно остается, но часть потребностей мы можем закрыть этим пакетом, например сопоставить тип MIME и расширение, или наоборот. Но перед этим нужно корректно определить тип файла.
Работает он с версией PHP 5.4 и выше. Установка пакета через composer:
composer require ralouphie/mimey
Пакет позволяет добавлять произвольные типы и их расширения, т. е. пакет можно расширять.
Вывод: работает только с текстом и отлично справляется (хорошая база). Не работает с файлами.
Пакет PHP Mime Detector
Пакет довольно молодой и косяки на лицо, даже еще сыроват. Суть у пакета такая же, как у стандартной функции PHP - определение типа файла по ему содержимому.
Все упирается в БД. Тут она небольшая, да и пока много кода на использование пакета.
Мне мешает тут отладка, я не хочу получать раздутые методы.
Вывод: сами разработчики нацелены на использование этого пакета, где нет поддержки FileInfo на сервере (но при этом поддержка PHP 7.1), а также на безопасное определение типа файла (чтоб 100% было точно). Пакет можно использовать, но с такими файлами как мне нужно - нет.
P.S. Если вы используете стандартный пакет FileInfo, то большая вероятность, что вам не понадобиться данный пакет (маленькая база).
Пакет PhpMimeType v2
Тут очень странно (описание со страницы пакета): простой PHP-класс для угадывания MIME-типа файла на основе расширения файла с возможностью использования в проекте Symfony.
Ну и сразу пример:
Если рассматривать файл PHP как пример разбора, то он может иметь минимум 6 возможных вариантов проверки, кроме этого, если парсить сам файла для определения типа, придется обойти весь файл в поисках возможных выводов php, а еще лучше выполнить его. Кроме этого, файл php может быть вообще без скрипта php.
Вывод: данный пакет достаточно популярен (много скачиваний), но его целесообразности я не вижу. Проще пользоваться Mimey и стандартной функцией FileInfo.
Пакет mm (davidpersson/mm)
Большой пакет рассчитанный на обработку медиафайлов. Он хоть и довольно старый (точнее давно не обновлялся), но некоторые функции для меня там присутствуют (определение группы файла).
Пример определения групп (он мне просто нужен):
Вывод: что-то может определять, но проще воспользоваться стандартными методами.
Пакет PhpMimeType
Пакет напоминает Mimey. Только функционал гораздо меньше, а библиотека (список поддерживаемых файлов) большая.
Однако есть небольшой минус: он определяет MIME-тпи файлов только по расширению.
Как было описано выше у PHP Mime Detector — небезопасно.
Пакет Mimey полностью может перекрыть функции данного пакета.
Вывод: определяет только по расширению. Mimey лучше.
Пакет blob-mimes
Пакет по своей базе достаточно обширный и основан на нескольких источниках о MIME.
Использует встроенные функции языка для определения типов и расширений файлов, а также сторонние расширения. На основе имеющейся БД уже делает выводы о типе файла.
Некоторые функции пакета: сравнение расширений и типов файла, возвращение массива других возможных расширений по текущему расширению и т. п.
Главное, есть функция, позволяющая определять по самому файлу тип файла (работает на основе стандартных функций PHP и множества зависимостей расширений для PHP).
Исходя из описания, пакет требует много расширений для PHP, и некоторые из них не установлены по умолчанию, и может быть на некоторых серверах без дополнительной платы не установят.
Данный пакет меня очень заинтересовал и возможно отвечает моим требованиям.
Проверив его результат меня немного порадовал, но без проблем не обошлось:
во время установки пакета, я заметил, что он тянет за собой лишние пакеты, которые (с моей точки зрения) вообще не нужны;
проведя свои тесты, часть из них было выполнено (вариант «адекватный пользователь», часть нет (подмена названий файлов).
Успешные результаты тестирования соответствовали результату пакета на Linux mimetype. А вот подмена имен файлов и содержимого не прошла тестирование. В большинстве случаев были ответы MIME-типов в соответствии с расширением файла. В одном случае выдал частично правильный результат (возможно по одному из стандартов он и действительный): php скрипт без расширения — результат text/x-php.
Но не стоит отчаиваться, т. к. и команда mimetype дала ложный результат переименовав rar-архив в apk-файл.
Результат команды mimetype: application/vnd.android.package-archive.
Результат обработки Blob-mimes: application/zip.
Необходимый результат: application/vnd.rar.
Вывод: пакет неплохо справляется со своими функциями, но к сожалению таких же результатов можно добиться с помощью обычной проверки расширения файла с обработкой исключений, но таких по факту (пакет PHP Mime Detector) или без обработки исключений, а только с расширением файла.
P.S. Разработчик ответив на результаты моих тестирований, подтвердил, что определения содержимого файла используется на основе сторонних библиотек. Остальная обработка определяется исходя из расширения файла.
Вывод
Просмотрев популярные и пакеты для получения расширений по файлу, я понял, что идеального решения нет, везде есть косяки и минусы. Нужно выбирать меньшее из двух зол.
Можно надеется, что стандартная функция php для определения типа файла всё-таки станет максимально точно определять MIME-тип (на крайняк, можно указать свои типы файлов).
Для тех, кто пользуется версиями ниже 7.2 и нужно просто конвертация типа файла или минимальная проверка, то можно воспользоваться стандартными средствами PHP и пакетом Mimey.
Для тех, кто пользуется версией 7.2 пакет Mimey уже не нужен будет, т. к. расширение FileInfo уже включает в себя эту функцию.
Для тех, кому нужен реальный MIME-тип файла (а это скорее всего в том случае, если вы хотите обработать данный файл: переконвертировать, изменить, создать модификацию), тому нужно проверять тип файла на содержимое. Если содержимое файла отличается от стандартных общеизвестных (image, audio, video и другими типами неизвестными для FileInfo), то стоит воспользоваться сторонними пакетами, но если ваш сервер на Linux есть возможность использования системных утилит, то ими можно воспользоваться (например, mimetype).
Но для себя я сделал вывод, что если и нужна обработка файла (а мне она для некоторых типов файлов нужна), то лучше это делать в обработчике файлов, т. к. там вы сможете с точностью 99% проверить на соответствие обрабатываемого файла. Тем самым, вы сможете минимизировать размеры пакетов и используемых расширений.
Поэтому, в своем случае, я пересмотрел подход к обработке файлов и решил воспользоваться именно последним выводом (меньше геморроя на всех этапах). В случае несовпадения типа MIME, будет отказ в обработке.
От второй своей задачи я также наверное откажусь (группировка файлов по типам), т. к. уже заметил по существующим пакетам, что одни и те же файлы могут относить к разным группам. Поэтому каждый сам решает, какая группа ему нужна. Кроме этого, возможно проще воспользоваться не группами, а категориями (каталогами). Потому что файлы изображений могут оказаться документами (фото или сканы), а аудио-файлы не музыкой, а записью разговора и т.п. А для фильтраций и общей группировки файлов использовать списки не хранящиеся в БД, тогда БД станет более универсальной, но возможно время обработки немного увеличится.
Как мы уже знаем, на сервере может храниться информация абсолютно разных форматов – изображения, аудиофайлы, документы и т.д. Когда клиент делает запрос на сервер, он (если все хорошо) получает в ответ то, что просил. И вот тут возникает проблема. Как клиент может определить, какие именно данные пришли с сервера, какой тип данных? Ведь картинки бывают разных форматов, документы бывают разных форматов.
Прежде чем веб-браузер покажет пользователю информацию, он должен правильно определить, что это за информация, чтобы правильно ее обработать. То есть нужен какой-то механизм согласования между сервером и клиентом, чтобы не было путаницы с разными форматами данных.
Так и появился механизм, который называется MIME-типы.
Когда браузер в ответ на свой вопрос получает какой-то объект данных, он в первую очередь ищет и смотрит на эту метку, чтобы понять, какие данные пришли и может ли браузер вообще их обработать.
Вот и все, на самом деле ничего сложного. Давайте посмотрим на практике, как это происходит.
Первым делом необходимо ознакомиться со всем списком утвержденных MIME-типов. Это можно сделать, например, на сайте Википедии.
Есть общие типы, описывающие документ, и есть подтипы, чтобы более подробно определить нужный формат. Например: application/pdf , text/html , image/png .
Стоит отметить, что если браузер не найдет MIME-тип у документа, то он попытается определить его самостоятельно. Однако это не всегда бывает успешно. Поэтому при разработке веб-приложений и передаче данных клиенту рекомендуется всегда явно также указывать соответствующий файлу MIME-тип.
Наглядная демонстрация, как и где определить MIME-тип для нужного файла, доступна на видео выше.
Читайте также: