Replacement for File::mime() in Laravel 4 (to get mime type from file extension)
Solution 1
One solution I've found is to use the Symfony HttpFoundation File class (which is already included as a dependency in Laravel 4):
$file = new Symfony\Component\HttpFoundation\File\File($path);
$mime = $file->getMimeType();
And in fact the File class uses the Symfony MimeTypeGuesser class so this also works:
$guesser = Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser::getInstance();
echo $guesser->guess($path);
But unfortunately I'm getting unexpected results: I'm getting text/plain instead of text/css when passing a path to a css file.
Solution 2
IF you had just uploaded the file you can use:
Input::file('field_name')->getMimeType();
You can see more here! I hope it be for some help! :D
EDIT:
Input::file
is some kind of extention from File
, so you may use File::get('file')->getMimeType();
also. Didn't test, but MUST work.
Solution 3
After reading that:
- PHP mime_content_type() is deprecated
- Its replacement FileInfo is unreliable
- Symfony's getMimeType() uses FileInfo (see my other answer)
I decided instead to port Laravel 3's implementation of File::mime() into a helper library within my Laravel 4 application. The Laravel 3 implementation just reads the MIME types from a config lookup array, based on file extension.
Solution:
- Copied application/config/mimes.php from my L3 project to app/config/mimes.php in my L4 project
- Made a FileHelper library with the File::mime() function code from the Laravel 3 File class.
Solution 4
It turned out that Symfony ExtensionGuesser
and MimeTypeGuesser
use unreliable FileInfo
class. For that reason validation of mimes return unpredictable results and can not be used with files uploads in a proper way (it returns text/plain
mime for js
, xls
, po
etc.).
I've found very simple solution for this problem.
Instead of
'attachment' => 'required|mimes:jpg,jpeg,bmp,png,doc,docx,zip,rar,pdf,rtf,xlsx,xls,txt|max:10000',
I split that into two different parts and now my validation looks like this:
private function createFileAttachmentValidator($file)
{
return Validator::make(
[
'attachment' => $file,
'extension' => \Str::lower($file->getClientOriginalExtension()),
],
[
'attachment' => 'required|max:10000',
'extension' => 'required|in:jpg,jpeg,bmp,png,doc,docx,zip,rar,pdf,rtf,xlsx,xls,txt',
],
$this->validationMessages()
);
}
I simply try to verify that extension of the file is present and that it is listed in my in
rule. That works, however, solution is not perfect.
Solution 5
public function mimeType($path)
{
return finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path);
}
Ref: https://github.com/illuminate/filesystem/blob/master/Filesystem.php#L194
mtmacdonald
Senior Software engineer at Oliasoft. I build web apps (full stack developer).
Updated on August 29, 2020Comments
-
mtmacdonald over 3 years
Laravel 3 had a File::mime() method which made it easy to get a file's mime type from its extension:
$extension = File::extension($path); $mime = File::mime($extension);
On upgrading to Laravel 4 I get an error:
Call to undefined method Illuminate\Filesystem\Filesystem::mime()
I also can't see any mention of mime types in the Filesystem API docs.
What's the recommended way to get a file's mime type in Laravel 4 (please note this is not a user-uploaded file)?
-
mtmacdonald over 10 yearsthanks, but as stated I want to use this for any general file, not one that has just been uploaded.
-
mtmacdonald over 10 years
-
mtmacdonald over 10 yearsthanks. But File::get() returns a string, so it is not possible to call getMimeType(). Also, Symfony's getMimeType() is not proving reliable for the CSS file type I need it to work for (see my own answer).
-
Dennis Braga over 10 yearsYeah, it seems to be a bug on Laravel I guess. Have you looked on Laravel's GitHub repository? You should look into the issue traking, see if you find something!
-
kovpack over 9 yearsThe same problem with text/plain instead of tons of other formats. js, txt, xls, po etc. - all get text/plain mimes
-
kovpack over 9 yearsThat method is unreliable. And useless as a result.
-
Manpreet almost 5 yearsUsing this along with built in mime validation is best way to tackle this.