Ok, I\'m trying to upload a video, and validate the file type.
According to the documentation:
mimes:foo,bar,...
This is expected behaviour.
Laravel is calling guessExtension on Symphony's UploadedFile object, which will return the expected extension of the file, not the mimetype.
This is why the documenatation states that for an uploaded image you should use:
'photo' => 'mimes:jpeg,bmp,png'
Symfony's guessExtension
calls getMimeType
, which uses PHP's Fileinfo Functions to go and guess the mimetype of a given file.
Once getMimeType
guesses the mimetype for the file, Symfony's MimeTypeExtensionGuesser kicks in to get the extension from the mime type retrieved from a file.
// ... 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',
Therefore, your rules should be:
return [
'file' => ['required', 'mimes:wmv,asf']
]
The reason that asf
should be included is mainly historical. To quote Wikipedia:
The most common media contained within an ASF file are Windows Media Audio (WMA) and Windows Media Video (WMV). The most common file extensions for ASF files are extension .WMA (audio-only files using Windows Media Audio, with MIME-type '
audio/x-ms-wma
') and .WMV (files containing video, using the Windows Media Audio and Video codecs, with MIME-type 'video/x-ms-asf
'). These files are identical to the old .ASF files but for their extension and MIME-type.
Microsoft's documentation about the difference between ASF and WMV/WMA files states:
The only difference between ASF files and WMV or WMA files are the file extensions and the MIME types [...] The basic internal structure of the files is identical.
Because the internal structure of the file is identical (including the magic numbers for the file format), wmv, wma and asf are one and the same. The only difference between the three extensions is the icon that is shown inside Explorer.
It's not just Windows Media files that will have this issue, Wikipedia lists many different video container formats that will have the same problem. If you want to find the video codec that is being used in a container, you are going to need to look at more then just the "magic patterns" that are used by the fileinfo
functions.
That being said, expected behaviour != correct behaviour.
I submitted a pull request to add a new validator, called mimetypes
. This does as you would expect and uses the guessed mimetype to validate an uploaded file, instead of the extension that is guessed from the mimetype.