Replacement for File::mime() in Laravel 4 (to get mime type from file extension)

22,723

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:

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

Share:
22,723
mtmacdonald
Author by

mtmacdonald

Senior Software engineer at Oliasoft. I build web apps (full stack developer).

Updated on August 29, 2020

Comments

  • mtmacdonald
    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
    mtmacdonald over 10 years
    thanks, but as stated I want to use this for any general file, not one that has just been uploaded.
  • mtmacdonald
    mtmacdonald over 10 years
    It seems from related questions that this isn't a reliable method.
  • mtmacdonald
    mtmacdonald over 10 years
    thanks. 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
    Dennis Braga over 10 years
    Yeah, 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
    kovpack over 9 years
    The same problem with text/plain instead of tons of other formats. js, txt, xls, po etc. - all get text/plain mimes
  • kovpack
    kovpack over 9 years
    That method is unreliable. And useless as a result.
  • Manpreet
    Manpreet almost 5 years
    Using this along with built in mime validation is best way to tackle this.