Fileinfo 函数
在线手册:中文 英文
PHP手册

mime_content_type

(PHP 4 >= 4.3.0, PHP 5)

mime_content_typeDetect MIME Content-type for a file (deprecated)

说明

string mime_content_type ( string $filename )

Returns the MIME content type for a file as determined by using information from the magic.mime file.

参数

filename

Path to the tested file.

返回值

Returns the content type in MIME format, like text/plain or application/octet-stream.

注释

Warning

This function has been deprecated as the PECL extension Fileinfo provides the same functionality (and more) in a much cleaner way.

范例

Example #1 mime_content_type() Example

<?php
echo mime_content_type('php.gif') . "\n";
echo 
mime_content_type('test.php');
?>

以上例程会输出:

image/gif
text/plain

参见


Fileinfo 函数
在线手册:中文 英文
PHP手册
PHP手册 - N: Detect MIME Content-type for a file (deprecated)

用户评论:

Josh Sean (06-Mar-2012 03:04)

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[]='&nbsp;&nbsp;&nbsp;\''.$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.

john dot howard at prismmg dot com (26-Oct-2009 11:43)

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);
}
?>

Bob (21-Jun-2009 12:25)

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.

svogal (27-Dec-2008 03:17)

<?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';
        }
    }
}
?>

geompse (22-Sep-2008 07:46)

Lukas 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);
}

Curtiss (19-Sep-2008 02:25)

I'm not sure if anyone is still using the functions shown below (I'm guessing someone must still be, since the latest update to the functions was made a few months ago), but I think you'd be better off using an explode statement rather than the regex shown in most of the functions to find the filesuffix.

The regex shown is only going to catch files with extensions between 2 and 4 characters. While filenames with more or less than that are extremely rare, they do exist. If you open the regex up to start accepting those types of things, however, you're making your life complicated for no reason.

In addition, I don't see the need for the overhead produced by the preg_match function when you could just use the explode and array_pop functions together.

If you explode the filename, using the dot as a separator, you can simply pop the last element off of the array to get the real file extension, no matter how short or long it is, without the overhead of a regex (unless one of those functions calls a regex in the background of which I'm not aware).

Therefore, where the regex would return no results on something like:
/var/www/html/example.backup
or
/var/www/html/example-program.c

the explode function would simply split it wherever it finds a dot and you can pop the last one off:

<?php
$filename
= '/var/www/html/example.backup';
$finfo = explode('.',$filename);
$fileSuffix = array_pop($finfo);
?>

Then, to put the rest of the file name back together, you can use the implode function on the remainder of the finfo array. Alternatively, when putting the rest of the file name back together, you could use the str_replace function to replace the dot and the extension with nothing, but then you run the rare risk of removing the same string from the middle of the file name somewhere (not very likely, but possible nonetheless).

Also, on a side note, the last function example is going to return the wrong value if the file extension is not in the list and the mime_content_type function exists. Because that part of the function re-sets the $fileSuffix variable, without returning a value, the function is going to move on to the next statement, which is only going to return the first letter of whatever was returned by the mime_content_type function.

Instead of reading:
<?php
           
if(function_exists("mime_content_type"))
            {
               
$fileSuffix = mime_content_type($filename);
            }
?>
it should read:
<?php
           
if(function_exists("mime_content_type"))
            {
                return
mime_content_type($filename);
            }
?>

php [spat] hm2k.org (21-Aug-2008 06:52)

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.

lukas v (10-Jul-2008 01:57)

I cleaned up and compiled together code from different people here below. This code returns "unknown/<filesuffix>" if it can't something better.

<?php
   
function returnMIMEType($filename)
    {
       
preg_match("|\.([a-z0-9]{2,4})$|i", $filename, $fileSuffix);

        switch(
strtolower($fileSuffix[1]))
        {
            case
"js" :
                return
"application/x-javascript";

            case
"json" :
                return
"application/json";

            case
"jpg" :
            case
"jpeg" :
            case
"jpe" :
                return
"image/jpg";

            case
"png" :
            case
"gif" :
            case
"bmp" :
            case
"tiff" :
                return
"image/".strtolower($fileSuffix[1]);

            case
"css" :
                return
"text/css";

            case
"xml" :
                return
"application/xml";

            case
"doc" :
            case
"docx" :
                return
"application/msword";

            case
"xls" :
            case
"xlt" :
            case
"xlm" :
            case
"xld" :
            case
"xla" :
            case
"xlc" :
            case
"xlw" :
            case
"xll" :
                return
"application/vnd.ms-excel";

            case
"ppt" :
            case
"pps" :
                return
"application/vnd.ms-powerpoint";

            case
"rtf" :
                return
"application/rtf";

            case
"pdf" :
                return
"application/pdf";

            case
"html" :
            case
"htm" :
            case
"php" :
                return
"text/html";

            case
"txt" :
                return
"text/plain";

            case
"mpeg" :
            case
"mpg" :
            case
"mpe" :
                return
"video/mpeg";

            case
"mp3" :
                return
"audio/mpeg3";

            case
"wav" :
                return
"audio/wav";

            case
"aiff" :
            case
"aif" :
                return
"audio/aiff";

            case
"avi" :
                return
"video/msvideo";

            case
"wmv" :
                return
"video/x-ms-wmv";

            case
"mov" :
                return
"video/quicktime";

            case
"zip" :
                return
"application/zip";

            case
"tar" :
                return
"application/x-tar";

            case
"swf" :
                return
"application/x-shockwave-flash";

            default :
            if(
function_exists("mime_content_type"))
            {
               
$fileSuffix = mime_content_type($filename);
            }

            return
"unknown/" . trim($fileSuffix[0], ".");
        }
    }
?>

MKoper (01-Jul-2008 09:29)

Regarding serkanyersen's example, i extended the extensions list

case "js":
                return "application/x-javascript";
            case "json":
                return "application/json";
            case "jpg":
            case "jpeg":
            case "jpe":
                return "image/jpg";
            case "png":
            case "gif":
            case "bmp":
            case "tiff":
                return "image/".strtolower($matches[1]);
            case "css":
                return "text/css";
            case "xml":
                return "application/xml";
            case "doc":
            case "docx":
                return "application/msword";
            case "xls":
            case "xlt":
            case "xlm":
            case "xld":
            case "xla":
            case "xlc":
            case "xlw":
            case "xll":
                return "application/vnd.ms-excel";
            case "ppt":
            case "pps":
                return "application/vnd.ms-powerpoint";
            case "rtf":
                return "application/rtf";
            case "pdf":
                return "application/pdf";
            case "html":
            case "htm":
            case "php":
                return "text/html";
            case "txt":
                return "text/plain";
            case "mpeg":
            case "mpg":
            case "mpe"
                return "video/mpeg";
            case "mp3":
                return "audio/mpeg3";
            case "wav":
                return "audio/wav";
            case "aiff":
            case "aif":
                return "audio/aiff";
            case "avi":
                return "video/msvideo";
            case "wmv":
                return "video/x-ms-wmv";
            case "mov":
                return "video/quicktime";
            case "zip":
                return "application/zip";
            case "tar":
                return "application/x-tar";
            case "swf":
                return "application/x-shockwave-flash";

memi aet liip doet ch (06-Jun-2008 10:59)

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.

serkanyersen (29-Apr-2008 04:22)

I've written an alternative for this. Not necessarily tested but it works OK on my server.

I hope this helps

<?php
/**
 * Tries to get mime data of the file.
 * @return {String} mime-type of the given file
 * @param $filename String
 */
function get_mime($filename){
   
preg_match("/\.(.*?)$/", $filename, $m);    # Get File extension for a better match
   
switch(strtolower($m[1])){
        case
"js": return "application/javascript";
        case
"json": return "application/json";
        case
"jpg": case "jpeg": case "jpe": return "image/jpg";
        case
"png": case "gif": case "bmp": return "image/".strtolower($m[1]);
        case
"css": return "text/css";
        case
"xml": return "application/xml";
        case
"html": case "htm": case "php": return "text/html";
        default:
            if(
function_exists("mime_content_type")){ # if mime_content_type exists use it.
              
$m = mime_content_type($filename);
            }else if(
function_exists("")){    # if Pecl installed use it
              
$finfo = finfo_open(FILEINFO_MIME);
              
$m = finfo_file($finfo, $filename);
              
finfo_close($finfo);
            }else{   
# if nothing left try shell
              
if(strstr($_SERVER[HTTP_USER_AGENT], "Windows")){ # Nothing to do on windows
                  
return ""; # Blank mime display most files correctly especially images.
              
}
               if(
strstr($_SERVER[HTTP_USER_AGENT], "Macintosh")){ # Correct output on macs
                  
$m = trim(exec('file -b --mime '.escapeshellarg($filename)));
               }else{   
# Regular unix systems
                  
$m = trim(exec('file -bi '.escapeshellarg($filename)));
               }
            }
           
$m = split(";", $m);
            return
trim($m[0]);
    }
}
?>

mami at madagascarsurlenet dot com (14-Nov-2007 06:58)

Since I enabled the mime_magic extension on my IIS, I also got the error message "invalid magic file, disabled" in my phpinfo. After I add these lines to my php.ini, the message disappeared and it works great!

mime_magic.debug = Off
mime_magic.magicfile ="D:\PHP5\extras\magic.mime"

mime_magic.debug is by default off but without this line it fails. I'm using PHP 5.2.5.

Sune Jensen (29-Aug-2007 05:16)

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)

dt at php dot net (14-Jun-2007 04:18)

<?php
if (!function_exists('mime_content_type ')) {
    function
mime_content_type($filename) {
       
$finfo    = finfo_open(FILEINFO_MIME);
       
$mimetype = finfo_file($finfo, $filename);
       
finfo_close($finfo);
        return
$mimetype;
    }
}
?>

Quis at IHAVEGOTSPAMENOUGH dot omicidio dot nl (12-Feb-2007 05:28)

<?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 ;)

tree2054 using hotmail (04-Nov-2006 01:59)

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 ) ) ) ;
   }
}

?>

(16-Oct-2006 03:06)

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'.

webmaster at cafe-clope dot net (23-Feb-2006 01:31)

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).

some dude AT somewhere DOT com (07-Oct-2005 05:44)

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.

ginnsu at arcee dot ca (09-Mar-2005 06:14)

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"