(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)
mime_content_type — Detecta el tipo de contenido de un fichero
Devuelve el contenido MIME de un fichero utilizando las informaciones desde el fichero magic.mime.
filename
Devuelve el tipo de contenido en formato MIME, como
text/plain o application/octet-stream,
o false si ocurre un error.
En caso de fallo, se emitirá una advertencia de tipo E_WARNING .
Ejemplo #1 Ejemplo con mime_content_type()
<?php
echo mime_content_type('php.gif') . "\n";
echo mime_content_type('test.php');
?>El ejemplo anterior mostrará:
image/gif text/plain
Fast generation of uptodate mime types:
<?php
define('APACHE_MIME_TYPES_URL','http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types');
function generateUpToDateMimeArray($url){
$s=array();
foreach(@explode("\n",@file_get_contents($url))as $x)
if(isset($x[0])&&$x[0]!=='#'&&preg_match_all('#([^\s]+)#',$x,$out)&&isset($out[1])&&($c=count($out[1]))>1)
for($i=1;$i<$c;$i++)
$s[]=' \''.$out[1][$i].'\' => \''.$out[1][0].'\'';
return @sort($s)?'$mime_types = array(<br />'.implode($s,',<br />').'<br />);':false;
}
echo
generateUpToDateMimeArray(APACHE_MIME_TYPES_URL);
?>
Output:
$mime_types = array(
'123' => 'application/vnd.lotus-1-2-3',
'3dml' => 'text/vnd.in3d.3dml',
'3g2' => 'video/3gpp2',
'3gp' => 'video/3gpp',
'7z' => 'application/x-7z-compressed',
'aab' => 'application/x-authorware-bin',
'aac' => 'audio/x-aac',
'aam' => 'application/x-authorware-map',
'aas' => 'application/x-authorware-seg',
...
Enjoy.I also had issues with this function.
The issue was that it would almost always return "text/plain".
echo ini_get('mime_magic.magicfile'); // returns /etc/httpd/conf/magic
I found that I needed the OS' magic.mime file instead.
You can either copy it to the existing location, or update your php.ini, you cannot use ini_set().
[root@blade conf]# mv magic magic.old
[root@blade conf]# cp /usr/share/magic.mime magic
[root@blade conf]# apachectl graceful
Note: you will see that I have gracefully restarted apache to ensure it has taken affect.There is a composer package that will do this:
https://github.com/ralouphie/mimey
<?php
$mimes = new \Mimey\MimeTypes;
// Convert extension to MIME type:
$mimes->getMimeType('json'); // application/json
// Convert MIME type to extension:
$mimes->getExtension('application/json'); // jsonLukas V is IMO missing some point. The MIME type of a file may not be corresponding to the file suffix.
Imagine someone would obfuscate some PHP code in a .gif file, the file suffix would be 'GIF' but the MIME would be text/plain or even text/html.
Another example is files fetched via a distant server (wget / fopen / file / fsockopen...). The server can issue an error, i.e. 404 Not Found, wich again is text/html, whatever you save the file to (download_archive.rar).
His provided function should begin by the test of the function existancy like :
function MIMEalternative($file)
{
if(function_exists('mime_content_type'))
return mime_content_type($file);
else
return <lukas_v.MIMEfunction>($file);
}using
<?php
function detectFileMimeType($filename='')
{
$filename = escapeshellcmd($filename);
$command = "file -b --mime-type -m /usr/share/misc/magic {$filename}";
$mimeType = shell_exec($command);
return trim($mimeType);
}
?>
should work on most shared linux hosts without errors. It should also work on Windows hosts with msysgit installed.I see a lot of comments suggesting doing file extension sniffing (i.e. assuming .jpg files are JPEG images) when proper file-type sniffing functions are unavailable.
I want to point out that there is a much more accurate way.
If neither mime_content_type() nor Fileinfo is available to you and you are running *any* UNIX variant since the 70s, including Mac OS, OS X, Linux, etc. (and most web hosting is), just make a system call to 'file(1)'.
Doing something like this:
<?php
echo system("file -bi '<file path>'");
?>
will output something like "text/html; charset=us-ascii". Some systems won't add the charset bit, but strip it off just in case.
The '-bi' bit is important. However, you can use a command like this:
<?php
echo system("file -b '<file path>'"); // without the 'i' after '-b'
?>
to output a human-readable string, like "HTML document text", which can sometimes be useful.
The only drawback is that your scripts will not work on Windows, but is this such a problem? Just about all web hosts use a UNIX.
It is a far better way than just examining the file extension.<?php
if(!function_exists('mime_content_type')) {
function mime_content_type($filename) {
$mime_types = array(
'txt' => 'text/plain',
'htm' => 'text/html',
'html' => 'text/html',
'php' => 'text/html',
'css' => 'text/css',
'js' => 'application/javascript',
'json' => 'application/json',
'xml' => 'application/xml',
'swf' => 'application/x-shockwave-flash',
'flv' => 'video/x-flv',
// images
'png' => 'image/png',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'gif' => 'image/gif',
'bmp' => 'image/bmp',
'ico' => 'image/vnd.microsoft.icon',
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'svg' => 'image/svg+xml',
'svgz' => 'image/svg+xml',
// archives
'zip' => 'application/zip',
'rar' => 'application/x-rar-compressed',
'exe' => 'application/x-msdownload',
'msi' => 'application/x-msdownload',
'cab' => 'application/vnd.ms-cab-compressed',
// audio/video
'mp3' => 'audio/mpeg',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
// adobe
'pdf' => 'application/pdf',
'psd' => 'image/vnd.adobe.photoshop',
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
// ms office
'doc' => 'application/msword',
'rtf' => 'application/rtf',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',
// open office
'odt' => 'application/vnd.oasis.opendocument.text',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
);
$ext = strtolower(array_pop(explode('.',$filename)));
if (array_key_exists($ext, $mime_types)) {
return $mime_types[$ext];
}
elseif (function_exists('finfo_open')) {
$finfo = finfo_open(FILEINFO_MIME);
$mimetype = finfo_file($finfo, $filename);
finfo_close($finfo);
return $mimetype;
}
else {
return 'application/octet-stream';
}
}
}
?>Completing <some dude AT somewhere DOT com> comment:
0 string < ? php application/x-httpd-php
and string detection on text files may fail if you check a file encoded with signed UTF-8. The UTF-8 signature is a two bytes code (0xFF 0xFE) that prepends the file in order to force UTF-8 recognition (you may check it on an hexadecimal editor).For me mime_content_type didn't work in Linux before I added
mime_magic.magicfile = "/usr/share/magic.mime"
to php.ini (remember to find the correct path to mime.magic)Converting mime types to extension in php (by Alex Corvi) :
https://gist.github.com/alexcorvi/df8faecb59e86bee93411f6a7967df2c Regarding serkanyersen's example : It is advisable to change the regular expression to something more precise like
preg_match("|\.([a-z0-9]{2,4})$|i", $filename, $m);
This makes sure that only the last few characters are taken. The original expression would not work if the filename is a relative path.if you use a transparent 'spacer' GIF i've found it needs to be a around 25x25 for it to register as 'image/gif'. otherwise it's read in as 'text/plain'.I added these two lines to my magic.mime file:
0 string \<?php application/x-httpd-php
0 string \<?xml text/xml
The first one may not work if "<?php" is not at the very beginning of your file, e.g., if some HTML preceeds the first bit of PHP code. The second one should work because "<?xml" *should* be the first thing in every XML file.Here's a simple function to return MIME types, based on the Apache mime.types file. [The one in my previous submission, which has since been replaced by this one] only works properly if mime.types is formatted as Windows text. The updated version below corrects this problem. Thanks to Mike for pointing this out.
<?php
function get_mime_type($filename, $mimePath = '../etc') {
$fileext = substr(strrchr($filename, '.'), 1);
if (empty($fileext)) return (false);
$regex = "/^([\w\+\-\.\/]+)\s+(\w+\s)*($fileext\s)/i";
$lines = file("$mimePath/mime.types");
foreach($lines as $line) {
if (substr($line, 0, 1) == '#') continue; // skip comments
$line = rtrim($line) . " ";
if (!preg_match($regex, $line, $matches)) continue; // no match to the extension
return ($matches[1]);
}
return (false); // no match at all
}
?>
Notes:
[1] Requires mime.types file distributed with Apache (normally found at ServerRoot/conf/mime.types). If you are using shared hosting, download the file with the Apache distro and then upload it to a directory on your web server that php has access to.
[2] First param is the filename (required). Second parameter is path to mime.types file (optional; defaults to home/etc/).
[3] Based on MIME types registered with IANA (http://www.iana.org/assignments/media-types/index.html). Recognizes 630 extensions associated with 498 MIME types.
[4] Asserts MIME type based on filename extension. Does not examine the actual file; the file does not even have to exist.
[5] Examples of use:
>> echo get_mime_type('myFile.xml');
>> application/xml
>> echo get_mime_type('myPath/myFile.js');
>> application/javascript
>> echo get_mime_type('myPresentation.ppt');
>> application/vnd.ms-powerpoint
>> echo get_mime_type('http://mySite.com/myPage.php);
>> application/x-httpd-php
>> echo get_mime_type('myPicture.jpg');
>> image/jpeg
>> echo get_mime_type('myMusic.mp3');
>> audio/mpeg
and so on...
To create an associative array containing MIME types, use:
<?php
function get_mime_array($mimePath = '../etc')
{
$regex = "/([\w\+\-\.\/]+)\t+([\w\s]+)/i";
$lines = file("$mimePath/mime.types", FILE_IGNORE_NEW_LINES);
foreach($lines as $line) {
if (substr($line, 0, 1) == '#') continue; // skip comments
if (!preg_match($regex, $line, $matches)) continue; // skip mime types w/o any extensions
$mime = $matches[1];
$extensions = explode(" ", $matches[2]);
foreach($extensions as $ext) $mimeArray[trim($ext)] = $mime;
}
return ($mimeArray);
}
?>The correct little correction:
exec will return the mime with a newline at the end, the trim() should be called with the result of exec, not the other way around.
<?php
if ( ! function_exists ( 'mime_content_type ' ) )
{
function mime_content_type ( $f )
{
return trim ( exec ('file -bi ' . escapeshellarg ( $f ) ) ) ;
}
}
?>// Here is a working version of a function that fetches the meme types from apache's built in mime list and creates an array of which the keys are the file extensions:
function generateUpToDateMimeArray($url){
$return = array();
$mimes = file_get_contents('http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types'); // make sure that allow_url_fopen is enabled!
preg_match_all('#^([^\s]{2,}?)\s+(.+?)$#ism', $mimes, $matches, PREG_SET_ORDER);
foreach ($matches as $match){
$exts = split(" ", $match[2]);
foreach ($exts as $ext){
$return[$ext]=$match[1];
}
}
return $return;
}
// usage:
$typeMime = generateUpToDateMimeArray();
echo $typeMime['gif'];The function mime_content_type only worked for me on Microsoft Windows after I added the directive "mime_magic.debug" to my php.ini with the value of "On". The default value appears to be "Off". Exampe:
[mime_magic]
mime_magic.debug = On
mime_magic.magicfile = "c:\php\extras\magic.mime"Slight improvement over Josh Sean's code: this makes a usable and formatted php file containing the latest mime associations ( strictly using the file extension) in an array or if the file_get_contents fails ( say you are offline ) leaves the original file alone.
I made it a bit "dummer" for readability purposes, don't judge me just improve it on your own.
<?php
define('APACHE_MIME_TYPES_URL','http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types');
function generateUpToDateMimeArray($url){
$s=array();
$result = @file_get_contents($url);
if ($result == FALSE )
{
$returned = "ERROR";
}
else
{
foreach(@explode("\n",$result)as $x)
{
if(isset($x[0])&&$x[0]!=='#'&&preg_match_all('#([^\s]+)#',$x,$out)&&isset($out[1])&&($c=count($out[1]))>1)
for($i=1;$i<$c;$i++)
$s[]=' \''.$out[1][$i].'\' => \''.$out[1][0].'\'';
}
$returned = @sort($s)?'<?php' . "\n" . '$mime_types = array(' . "\n" . implode($s,",\n") . "\n);\n" . '?>':false;
}
return $returned;
}
$file_name = 'mime-array.php';
$data = generateUpToDateMimeArray(APACHE_MIME_TYPES_URL);
if ($data != "ERROR")
{
$file = fopen($file_name, 'wb') or die("cannot open $file_name\n");
fwrite($file, $data ) or die("cannot write data\n");
fclose($file);
echo "updated";
}
else
{
echo "faliure";
}
?>
All you need to do is run it once and in your code you can simply add these two lines:
<?php
include 'mime-array.php';
global $mime_types;
?>
enjoy<?PHP
function qmimetype($file) {
$ext=array_pop(explode('.',$file));
foreach(file('/usr/local/etc/apache22/mime.types') as $line)
if(preg_match('/^([^#]\S+)\s+.*'.$ext.'.*$/',$line,$m))
return $m[1];
return 'application/octet-stream';
}
?>
Not perfect, but works good enough for me ;)