How do I find the mime-type of a file with php?

Ok, so I have an index.php file which has to process many different file types. how do I guess the filetype based on the REQUEST_URI.

If I request http://site/image.jpg, and all requests redirect through index.php, which looks like this

<?php
   include('/www/site'.$_SERVER['REQUEST_URI']);
?>

How would I make that work correctly?

Should I test based on the extension of the file requested, or is there a way to get the filetype?


Solution 1:

If you are sure you're only ever working with images, you can check out the getimagesize() exif_imagetype() PHP function, which attempts to return the image mime-type.

If you don't mind external dependencies, you can also check out the excellent getID3 library which can determine the mime-type of many different file types.

Lastly, you can check out the mime_content_type() function - but it has been deprecated for the Fileinfo PECL extension.

Solution 2:

mime_content_type() is deprecated, so you won't be able to count on it working in the future. There is a "fileinfo" PECL extension, but I haven't heard good things about it.

If you are running on a *nix server, you can do the following, which has worked fine for me:

$file = escapeshellarg( $filename );
$mime = shell_exec("file -bi " . $file);
$filename should probably include the absolute path.

Solution 3:

function get_mime($file) {
  if (function_exists("finfo_file")) {
    $finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
    $mime = finfo_file($finfo, $file);
    finfo_close($finfo);
    return $mime;
  } else if (function_exists("mime_content_type")) {
    return mime_content_type($file);
  } else if (!stristr(ini_get("disable_functions"), "shell_exec")) {
    // http://stackoverflow.com/a/134930/1593459
    $file = escapeshellarg($file);
    $mime = shell_exec("file -bi " . $file);
    return $mime;
  } else {
    return false;
  }
}

For me, nothing of this does work - mime_content_type is deprecated, finfo is not installed, and shell_exec is not allowed.

Solution 4:

I actually got fed up by the lack of standard MIME sniffing methods in PHP. Install fileinfo... Use deprecated functions... Oh these work, but only for images! I got fed up of it, so I did some research and found the WHATWG Mimesniffing spec - I believe this is still a draft spec though.

Anyway, using this specification, I was able to implement a mimesniffer in PHP. Performance is not an issue. In fact on my humble machine, I was able to open and sniff thousands of files before PHP timed out.

Here is the MimeReader class.

require_once("MimeReader.php");

$mime = new MimeReader(<YOUR FILE PATH>);
$mime_type_string = $mime->getType();     // "image/jpeg" etc.