2024年PHP开发者大会日本站

mime_content_type

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

mime_content_type检测文件的MIME内容类型

描述

mime_content_type(资源|字符串 $filename): 字符串|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

参见

添加备注

用户贡献的笔记 20条笔记

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
16年前
在我看来,Lukas V 遗漏了一些要点。文件的MIME类型可能与文件后缀不对应。

想象一下,有人在一个.gif文件中混淆了一些PHP代码,文件后缀将是'GIF',但MIME将是text/plain甚至text/html。

另一个例子是从远程服务器获取的文件(wget / fopen / file / fsockopen...)。服务器可能会发出错误,例如404未找到,这又是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年前
我看到很多评论建议在没有合适的filetype嗅探功能时进行文件扩展名嗅探(即假设.jpg文件是JPEG图像)。
我想指出,有一种更准确的方法。
如果您既没有 `mime_content_type()` 也 没有 Fileinfo 可用,并且您正在运行自 70 年代以来的任何 UNIX 变体,包括 Mac OS、OS X、Linux 等(以及大多数 Web 托管),只需对“file(1)”进行系统调用。
像这样操作
<?php
echo system("file -bi '<文件路径>'");
?>
将输出类似“text/html; charset=us-ascii”的内容。某些系统不会添加字符集位,但以防万一,请将其删除。
“-bi”位很重要。但是,您可以使用这样的命令
<?php
echo system("file -b '<文件路径>'"); // “-b”后没有“i”
?>
输出人类可读的字符串,例如“HTML 文档文本”,这有时可能很有用。
唯一的缺点是您的脚本无法在 Windows 上运行,但这算问题吗?几乎所有 Web 主机都使用 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',

// 图片
'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',

// 压缩文件
'zip' => 'application/zip',
'rar' => 'application/x-rar-compressed',
'exe' => 'application/x-msdownload',
'msi' => 'application/x-msdownload',
'cab' => 'application/vnd.ms-cab-compressed',

// 音频/视频
'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',

// Microsoft 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';
}
}
}
?>
匿名用户
18年前
如果您使用透明的“间隔符”GIF,我发现它需要大约 25x25 大小才能注册为“image/gif”。否则它会被读取为“text/plain”。
Sune Jensen
17年前
在我添加以下内容到 php.ini 之前,`mime_content_type` 在我的 Linux 系统上不起作用

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

(记住找到 `mime.magic` 的正确路径)
webmaster at cafe-clope dot net
18年前
补充 <some dude AT somewhere DOT com> 的评论

0 字符串 < ? php application/x-httpd-php

并且如果检查使用带签名的 UTF-8 编码的文件,文本文件的字符串检测可能会失败。UTF-8 签名是两个字节的代码 (0xFF 0xFE),它预先添加到文件中以强制识别 UTF-8(您可以在十六进制编辑器中检查它)。
php [spat] hm2k.org
16年前
我也遇到了此函数的问题。

问题是它几乎总是返回“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
18年前
正确的细微修正

`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
19年前
我在我的 magic.mime 文件中添加了这两行

0 字符串 \<?php application/x-httpd-php
0 字符串
\<?xml text/xml

第一种方法可能无效
如果 "<?php" 不在文件的开头例如,如果 一些 HTML 代码位于 PHP 代码之前第二种方法应该有效,因为 "<?xml" *应该* 是每个 XML 文件的第一行
john dot howard at prismmg dot com
15年前
这是一个简单的函数,用于根据 Apache 的 mime.types 文件返回 MIME 类型。[我之前提交的版本,现在已被此版本替换] 只有在 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; // 跳过注释
$line = rtrim($line) . " ";
if (!
preg_match($regex, $line, $matches)) continue; // 与扩展名不匹配
return ($matches[1]);
}
return (
false); // 完全不匹配
}
?>

注释
[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; // 跳过注释
if (!preg_match($regex, $line, $matches)) continue; // 跳过没有扩展名的 MIME 类型
$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'); // 确保启用了 allow_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
9年前
对 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("无法打开 $file_name\n");
fwrite($file, $data ) or die("无法写入数据\n");
fclose($file);
echo
"更新成功";
}
else
{
echo
"失败";
}

?>
只需运行一次,然后在代码中添加这两行即可

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

不完美,但对我来说足够用了;)
mami at madagascarsurlenet dot com
17年前
自从我在我的IIS上启用了mime_magic扩展,我也收到了我的phpinfo中的“无效的magic文件,已禁用”错误消息。在我将这些行添加到我的php.ini之后,消息消失了,并且运行良好!

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

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