Laravel 5 Mime validation

Хорошо, я пытаюсь загрузить видео и проверить тип файла.

Согласно документации:

мимы: Foo, бар,...

Файл под проверкой должен иметь тип MIME, соответствующий одному из перечисленных расширений.

Основное использование правила MIME

'photo' = > 'mimes: jpeg, bmp, png'

Я загружаю wmv-видео, и мои правила таковы:

return [
    'file' => ['required', 'mimes:video/x-ms-wmv']
]

Я сделал print_r() на Request::file('file'), и я получаю следующие данные:

Symfony\Component\HttpFoundation\File\UploadedFile Object
(
    [test:Symfony\Component\HttpFoundation\File\UploadedFile:private] => 
    [originalName:Symfony\Component\HttpFoundation\File\UploadedFile:private] => SampleVideo.wmv
    [mimeType:Symfony\Component\HttpFoundation\File\UploadedFile:private] => video/x-ms-wmv
    [size:Symfony\Component\HttpFoundation\File\UploadedFile:private] => 70982901
    [error:Symfony\Component\HttpFoundation\File\UploadedFile:private] => 0
    [pathName:SplFileInfo:private] => C:\wamp\tmp\php6428.tmp
    [fileName:SplFileInfo:private] => php6428.tmp
)

Однако я получаю сообщение об ошибке:

{"file":["The file must be a file of type: video\/x-ms-wmv."]}

Я попытался изменить "тип mime" на video/*, wmv (в соответствии с документами), а также video/x-ms-wmv, но никто из них не корректно проверяет файл.

Как видно из print_r(), тип mime Symfony получает video/x-ms-wmv.

Я что-то делаю неправильно? Или может Laravel/Symfony просто не проверять файлы?

Я ценю помощь

Edit Итак, я открыл validator.php и добавил echo $value->guessExtension(); к методу ValidateMimes(), и он выводит asf.

Почему вывод Symfony video\x-ms-wmv, расширение файла - wmv, я проверяю их оба, но Laravel гадает asf?!

Это слишком ненадежно для проверки видео для меня.

Ответ 1

Это ожидаемое поведение.

Laravel вызывает guessExtension в Symphony UploadedFile объект, который вернет ожидаемое расширение файла, а не тип mimetype.

Вот почему документация заявляет, что для загруженного изображения вы должны использовать:

'photo' = > 'mimes: jpeg, bmp, png'

Symfony guessExtension вызывает getMimeType, который использует PHP Fileinfo Functions, чтобы перейти и угадать тип mimetype данного файла.

Как только getMimeType угадывает тип mimetype для файла, Symfony MimeTypeExtensionGuesser запускает, чтобы получить расширение из типа mime, полученного из файл.

    // ... cut from MimeTypeExtensionGuesser
    'video/x-ms-asf' => 'asf',
    'video/x-ms-wmv' => 'wmv',
    'video/x-ms-wmx' => 'wmx',
    'video/x-ms-wvx' => 'wvx',
    'video/x-msvideo' => 'avi',

Поэтому ваши правила должны быть:

return [
    'file' => ['required', 'mimes:wmv,asf']
]

Причина, по которой asf должна быть включена, в основном историческая. Процитировать Wikipedia:

Наиболее распространенными носителями, содержащимися в файле ASF, являются Windows Media Audio (WMA) и Windows Media Video (WMV). Наиболее распространенными расширениями файлов для файлов ASF являются расширение .WMA(аудио файлы с использованием Windows Media Audio с типом MIME audio/x-ms-wma) и .WMV(файлы, содержащие видео, с использованием кодеков Windows Media Audio и Video, с MIME-тип 'video/x-ms-asf'). Эти файлы идентичны старым .ASF файлам, но для их расширения и MIME-типа.

Документация Microsoft о разница между файлами ASF и WMV/WMA гласит:

Единственная разница между файлами ASF и файлами WMV или WMA - это расширения файлов и типы MIME [...] Основная внутренняя структура файлов идентична.

Поскольку внутренняя структура файла идентична (включая магические числа для формата файла), wmv, wma и asf являются тоже самое. Единственное различие между тремя расширениями - это значок, который отображается внутри Проводника.

Это не просто файлы Windows Media, которые будут иметь эту проблему, Википедические списки в разных форматах видеоконтейнеров, которые будут иметь одинаковую проблему. Если вы хотите найти видеокодек, который используется в контейнере, вам нужно будет посмотреть больше, чем просто "magic patterns" , которые используются функциями fileinfo.


Сказанное, ожидаемое поведение!= правильное поведение.

Я отправил запрос , чтобы добавить новый валидатор под названием mimetypes. Это делает так, как вы ожидали, и использует угаданный тип mimetype для проверки загруженного файла вместо расширения, которое угадывается из типа mimetype.