mime_content_type

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

mime_content_type检测文件的 MIME 内容类型

说明

mime_content_type(resource|string $filename): string|false

使用 magic.mime 文件中的信息来确定文件的 MIME 内容类型。

参数

filename

要测试文件的路径。

返回值

以 MIME 格式返回内容类型,例如 text/plainapplication/octet-stream,或者在失败时返回 false

错误/异常

如果失败,将发出 E_WARNING

范例

范例 #1 mime_content_type() 范例

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

上面的例子将输出

image/gif
text/plain

参见

添加笔记

用户贡献的笔记 21 笔

Josh Sean
12 年前
快速生成最新的 MIME 类型

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

输出
$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',
...

尽情享用。
匿名
8 年前
有一个 Composer 包可以做到这一点
https://github.com/ralouphie/mimey

<?php
$mimes
= new \Mimey\MimeTypes;

// 将扩展名转换为 MIME 类型:
$mimes->getMimeType('json'); // application/json

// 将 MIME 类型转换为扩展名:
$mimes->getExtension('application/json'); // json
geompse
15 年前
Lukas V 遗漏了一些要点。文件的 MIME 类型可能与文件后缀不对应。

假设有人将一些 PHP 代码混淆到一个 .gif 文件中,文件后缀将是 'GIF',但 MIME 将是 text/plain 甚至 text/html。

另一个例子是通过远程服务器(wget / fopen / file / fsockopen...)获取的文件。服务器可能会发出错误,例如 404 Not Found,同样是 text/html,无论您将文件保存到哪里(download_archive.rar)。

他提供的函数应该以测试函数是否存在开始,例如

function MIMEalternative($file)
{
if(function_exists('mime_content_type'))
return mime_content_type($file);
else
return <lukas_v.MIMEfunction>($file);
}
Bond Akinmade
9 年前
使用
<?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);
}
?>
应该在大多数共享的 Linux 主机上正常工作,不会出现错误。它也应该在安装了 msysgit 的 Windows 主机上正常工作。
Bob
15 年前
我看到很多评论建议在没有合适的文件类型嗅探功能的情况下执行文件扩展名嗅探(即假设 .jpg 文件是 JPEG 图像)。
我想指出,有一种更准确的方法。
如果 mime_content_type() 和 Fileinfo 都不可用,并且您运行的是自 70 年代以来的任何 UNIX 变体,包括 Mac OS、OS X、Linux 等(以及大多数网络托管),只需对 'file(1)' 进行系统调用。
执行类似这样的操作
<?php
echo system("file -bi '<file path>'");
?>
将输出类似 "text/html; charset=us-ascii" 的内容。有些系统不会添加字符集部分,但为了保险起见,可以将其剥离。
'-bi' 部分很重要。但是,您可以使用类似这样的命令
<?php
echo system("file -b '<file path>'"); // 没有 '-b' 后的 'i'
?>
来输出一个人类可读的字符串,例如 "HTML 文档文本",这有时可能很有用。
唯一的缺点是您的脚本无法在 Windows 上运行,但这真的是一个问题吗?几乎所有网络主机都使用 UNIX。
这比仅仅检查文件扩展名要好得多。
svogal
15 年前
<?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';
}
}
}
?>
Anonymous
17 年前
如果你使用透明的“间隔符” GIF,我发现它需要大约 25x25 的大小才能被识别为“image/gif”。否则它会被读作“text/plain”。
webmaster at cafe-clope dot net
18 年前
补充 <some dude AT somewhere DOT com> 的评论

0 string < ? php application/x-httpd-php

以及对文本文件的字符串检测,如果你检查一个使用带签名的 UTF-8 编码的文件,可能会失败。UTF-8 签名是一个两个字节的代码 (0xFF 0xFE),它会放在文件开头,以强制识别 UTF-8(你可以在十六进制编辑器中查看它)。
Sune Jensen
16 年前
在我的 Linux 上,mime_content_type 无法工作,直到我添加了

mime_magic.magicfile = "/usr/share/magic.mime"

到 php.ini 文件中(记得找到 mime.magic 的正确路径)。
php [spat] hm2k.org
15 年前
我也有这个问题。

问题是它几乎总是返回“text/plain”。

echo ini_get('mime_magic.magicfile'); // 返回 /etc/httpd/conf/magic

我发现我需要操作系统的 magic.mime 文件。

你可以把它复制到现有位置,或者更新你的 php.ini 文件,不能使用 ini_set()。

[root@blade conf]# mv magic magic.old
[root@blade conf]# cp /usr/share/magic.mime magic
[root@blade conf]# apachectl graceful

注意:你会看到我已经优雅地重启了 apache,以确保它生效。
memi aet liip doet ch
16 年前
关于 serkanyersen 的例子:建议将正则表达式更改为更精确的表达式,例如

preg_match("|\.([a-z0-9]{2,4})$|i", $filename, $m);

这确保了只有最后几个字符被提取。如果文件名是相对路径,则原始表达式将无法工作。
tree2054 using hotmail
17 年前
正确的细微调整

exec 将返回带有换行符的 mime,trim() 应该调用 exec 的结果,而不是相反。

<?php

if ( ! function_exists ( 'mime_content_type ' ) )
{
function
mime_content_type ( $f )
{
return
trim ( exec ('file -bi ' . escapeshellarg ( $f ) ) ) ;
}
}

?>
some dude AT somewhere DOT com
18 年前
我在 magic.mime 文件中添加了这两行

0 string \<?php application/x-httpd-php
0 string
\<?xml text/xml

第一个可能无法工作,
如果"<?php" 不在你的文件的最开头e.g., 如果 一些 HTML 代码在第一段 PHP 代码之前. 第二个应该可以工作,因为"<?xml" *应该* 是每个 XML 文件的第一行
john dot howard at prismmg dot com
14 年前
这里有一个简单的函数来返回 MIME 类型,它基于 Apache 的 mime.types 文件。[我之前提交的函数,现在已经被这个函数替换了] 只有在 mime.types 文件以 Windows 文本格式编排时才能正常工作。下面的更新版本修正了这个问题。感谢 Mike 指出这一点。

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

注释
[1] 需要 Apache 分发的 mime.types 文件(通常位于 ServerRoot/conf/mime.types)。如果您使用的是共享主机,请使用 Apache 发行版下载该文件,然后将其上传到您的 Web 服务器上 php 可以访问的目录。

[2] 第一个参数是文件名(必需)。第二个参数是 mime.types 文件的路径(可选;默认为 home/etc/)。

[3] 基于在 IANA 注册的 MIME 类型 (http://www.iana.org/assignments/media-types/index.html)。识别与 498 种 MIME 类型关联的 630 种扩展名。

[4] 根据文件名扩展名断言 MIME 类型。不检查实际文件;该文件甚至不必存在。

[5] 使用示例
>> 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
等等...

要创建一个包含 MIME 类型的关联数组,请使用
<?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);
}
?>
alex at webedge dot ca
9 年前
// 下面是一个从 Apache 内置 MIME 列表中获取 meme 类型并创建一个以文件扩展名为键的数组的函数的工作版本

function generateUpToDateMimeArray($url){
$return = array();
$mimes = file_get_contents('http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types'); // 确保允许 url fopen!

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

// 用法

$typeMime = generateUpToDateMimeArray();
echo $typeMime['gif'];
ppaster at mailinator dot com
10 年前
除了 svogal 的视频文件
'mp4' => 'video/mp4',
还有这些工作
'mp4' => 'audio/mp4',
ginnsu at arcee dot ca
19 年前
只有在我将指令 "mime_magic.debug" 添加到我的 php.ini 中,并将值设置为 "On" 后,函数 mime_content_type 才能在我的 Microsoft Windows 上正常工作。默认值似乎是 "Off"。示例

[mime_magic]
mime_magic.debug = On
mime_magic.magicfile = "c:\php\extras\magic.mime"
jacopo dot mazzoni at gmail dot com
8 年前
对 Josh Sean 的代码略微改进:这使得一个可用的和格式化的 php 文件,其中包含最新的 mime 关联(严格使用文件扩展名)在一个数组中,或者如果 file_get_contents 失败(例如您处于脱机状态),则保留原始文件。
为了可读性,我让它变得有点“愚蠢”,不要评判我,只是自己改进它。

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

?>
您只需要运行它一次,在您的代码中,您只需添加这两行

<?php
include 'mime-array.php';
global
$mime_types;
?>

享受
Quis at IHAVEGOTSPAMENOUGH dot omicidio dot nl
17 年前
<?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';
}
?>

还不错,对我来说已经足够用了;)
David Spector
4年前
在Windows上,PHP 7.0.30报了错误“致命错误:未捕获的错误:调用未定义的函数 mime_content_type()”。我在我的Apache配置中看到了以下有趣的行

#LoadModule mime_magic_module modules/mod_mime_magic.so

所以我尝试取消注释它并重启Apache服务,但仍然得到相同的错误。在网上搜索发现这个函数已经过时了。似乎它已经从PHP中删除了。不知道为什么,但可以用用户函数来解决。
mami at madagascarsurlenet dot com
16 年前
自从我在我的IIS上启用了mime_magic扩展,我也收到了错误信息“无效的魔法文件,已禁用”在我的phpinfo中。在我将以下行添加到我的php.ini后,消息消失了,并且它运行良好!

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

mime_magic.debug默认情况下是关闭的,但如果没有这一行,它就会失败。我使用的是PHP 5.2.5。
To Top