How do I determine the extension(s) associated with a MIME type in PHP?
Solution 1
Not built-in, but it's not terribly hard to roll your own:
function system_extension_mime_types() {
# Returns the system MIME type mapping of extensions to MIME types, as defined in /etc/mime.types.
$out = array();
$file = fopen('/etc/mime.types', 'r');
while(($line = fgets($file)) !== false) {
$line = trim(preg_replace('/#.*/', '', $line));
if(!$line)
continue;
$parts = preg_split('/\s+/', $line);
if(count($parts) == 1)
continue;
$type = array_shift($parts);
foreach($parts as $part)
$out[$part] = $type;
}
fclose($file);
return $out;
}
function system_extension_mime_type($file) {
# Returns the system MIME type (as defined in /etc/mime.types) for the filename specified.
#
# $file - the filename to examine
static $types;
if(!isset($types))
$types = system_extension_mime_types();
$ext = pathinfo($file, PATHINFO_EXTENSION);
if(!$ext)
$ext = $file;
$ext = strtolower($ext);
return isset($types[$ext]) ? $types[$ext] : null;
}
function system_mime_type_extensions() {
# Returns the system MIME type mapping of MIME types to extensions, as defined in /etc/mime.types (considering the first
# extension listed to be canonical).
$out = array();
$file = fopen('/etc/mime.types', 'r');
while(($line = fgets($file)) !== false) {
$line = trim(preg_replace('/#.*/', '', $line));
if(!$line)
continue;
$parts = preg_split('/\s+/', $line);
if(count($parts) == 1)
continue;
$type = array_shift($parts);
if(!isset($out[$type]))
$out[$type] = array_shift($parts);
}
fclose($file);
return $out;
}
function system_mime_type_extension($type) {
# Returns the canonical file extension for the MIME type specified, as defined in /etc/mime.types (considering the first
# extension listed to be canonical).
#
# $type - the MIME type
static $exts;
if(!isset($exts))
$exts = system_mime_type_extensions();
return isset($exts[$type]) ? $exts[$type] : null;
}
Solution 2
You could use mime_content_type
but it is deprecated. Use fileinfo
instead:
function getMimeType($filename) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $filename);
finfo_close($finfo);
return $mime;
}
Solution 3
You might want to use this library: https://github.com/ralouphie/mimey
Example usage:
$mimes = new \Mimey\MimeTypes;
// Convert extension to MIME type:
$mimes->getMimeType('json'); // application/json
// Convert MIME type to extension:
$mimes->getExtension('application/json'); // json
This because apparently the quality of the provided PHP functions is dubious.
Solution 4
If you are working with vary limited extensions of images and need something very simple, I think this is enough.
switch($info['mime'])
{
case 'image/gif' : $extension = 'gif'; break;
case 'image/png' : $extension = 'png'; break;
case 'image/jpeg' : $extension = 'jpg'; break;
default :
throw new ApplicationException('The file uploaded was not a valid image file.');
break;
}
Related videos on Youtube
Alexander Trauzzi
Experienced full-stack developer and conference presenter with extensive knowledge in open source, software architecture and design patterns. Accomplishments range from defining company technical direction and leading teams to success while creating APIs and server-side infrastructure for mobile apps. Many of my interests center around software, spending my free time expanding my skills and learning new technologies.
Updated on September 28, 2020Comments
-
Alexander Trauzzi over 3 years
Is there a quick and dirty mapping of MIME types to extensions in PHP that I can make use of?
-
Mark Amery about 10 yearsPeople merely wanting to map extensions to MIME types, rather than the other way round, should note that there is now built-in support for this which they should take advantage of - see Jorge's answer rather than the accepted one.
-
Wranorn over 6 years@MarkAmery however as noted, finfo_file() requires that the file exists. Which isn't always the case. Chaos' answer is still more on point to the OP and still valid 8 years later.
-
-
Jorge Barata over 10 yearsI think this is an old answer. Now you should use
fileinfo
php.net/manual/en/ref.fileinfo.php -
Mark Amery about 10 yearsIt's worth noting that the OP actually asked to map MIME types to file extensions. This still covers the most common use case (and probably the one the OP was faced with), so it certainly deserves to exist and I've +1ed it, but it's not strictly an answer to the question that was asked as pedantically interpreted.
-
Pang almost 10 yearsNote:
finfo_file()
andmime_content_type()
requires that file exists. -
danronmoon over 9 years@JorgeB.G. That requires that the file exists, doesn't it?
-
Qix - MONICA WAS MISTREATED over 9 years@danronmoon. yes it does.
-
Greg almost 8 yearsWhere does it say that it is deprecated?
-
kloddant almost 3 yearsThis fails unless $filename is a string that it can read. It does not work on generic strings that do not correspond to files on the server.
-
Mouagip almost 3 yearsI wrote a small package to guess the MIME type based on the file extension (if the file does not exist or cannot be accessed): github.com/mzur/guess-mime