PHP Conference Japan 2024

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

傳回檔案的 MIME 內容類型,該類型由使用 magic.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 則註解

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

享受吧。
20
匿名
8 年前
有一個 composer 套件可以做到這點
https://github.com/ralouphie/mimey

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

// 將副檔名轉換為 MIME 類型:
$mimes->getMimeType('json'); // application/json

// 將 MIME 類型轉換為副檔名:
$mimes->getExtension('application/json'); // json
12
geompse
16 年前
我認為 Lukas V 遺漏了一些重點。檔案的 MIME 類型可能與檔案後綴不符。

想像一下,如果有人在 .gif 檔案中混淆了一些 PHP 程式碼,檔案後綴會是 '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);
}
9
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 主機上也可以運作。
6
Bob
15 年前
我看到很多評論建議在無法使用適當的檔案類型偵測函數時,進行檔案副檔名嗅探(例如,假設 .jpg 檔案是 JPEG 圖片)。
我想指出,其實有更準確的方法。
如果您無法使用 mime_content_type() 或 Fileinfo,而且您執行的系統是 70 年代以來的任何 UNIX 變種,包括 Mac OS、OS X、Linux 等(大多數網站伺服器都屬於此類),只要對 'file(1)' 進行系統呼叫即可。
像這樣執行:
<?php
echo system("file -bi '<檔案路徑>'");
?>
會輸出類似 "text/html; charset=us-ascii" 的內容。有些系統不會加上 charset 位元,但為了保險起見,最好將其去除。
'-bi' 位元很重要。不過,您可以使用像這樣的指令:
<?php
echo system("file -b '<檔案路徑>'"); // 在 '-b' 後面沒有 'i'
?>
來輸出人類可讀的字串,例如 "HTML document text",有時會很有用。
唯一的缺點是您的腳本將無法在 Windows 上運作,但這真的是個問題嗎?幾乎所有網站伺服器都使用 UNIX。
這比僅檢查檔案副檔名好太多了。
10
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',

// 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';
}
}
}
?>
1
Anonymous
18 年前
我發現,如果您使用透明的「間隔」GIF,它需要大約 25x25 像素才能被註冊為 'image/gif'。否則,它會被讀取為 'text/plain'。
1
Sune Jensen
17 年前
對我來說,在 Linux 中,在我加入以下設定之前,mime_content_type 無法運作:

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

到 php.ini (記得找到 mime.magic 的正確路徑)
1
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(您可以在十六進制編輯器中檢查它)。
0
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,以確保它已生效。
0
memi aet liip doet ch
16 年前
關於 serkanyersen 的範例:建議將正規表示式更改為更精確的表示式,例如:

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

這確保只取最後幾個字元。如果檔案名稱是相對路徑,則原始的表示式將無法運作。
0
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 ) ) ) ;
}
}

?>
0
some dude AT somewhere DOT com
19 年前
我在我的 magic.mime 檔案中加入了這兩行:

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

如果您的檔案開頭不是
"<?php"則第一個可能無法運作,例如,如果一些 HTML 在第一個 PHP 程式碼片段之前。第二個應該可以運作,因為"<?xml"*應該*是每個 XML 檔案中的第一件事
-1
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; // 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 發行版本下載該檔案,然後將其上傳到您的網頁伺服器上 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);
}
?>
-2
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'];
-5
ppaster at mailinator dot com
10 年前
svogal 的影片檔案補充
'mp4' => 'video/mp4',
以下也有效
'mp4' => 'audio/mp4',
-2
ginnsu at arcee dot ca
19 年前
只有在我的 php.ini 中將 "mime_magic.debug" 指令的值設為 "On" 之後,mime_content_type 函式才能在 Microsoft Windows 上正常運作。預設值似乎是 "Off"。例如

[mime_magic]
mime_magic.debug = On
mime_magic.magicfile = "c:\php\extras\magic.mime"
-3
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("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;
?>

請享用
-3
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';
}
?>

不完美,但對我來說夠用了 ;)
-5
mami at madagascarsurlenet dot com
17 年前
自從我在我的 IIS 上啟用了 mime_magic 擴充功能後,我的 phpinfo 中也出現了錯誤訊息「invalid magic file, disabled」。在我將這些行添加到我的 php.ini 後,訊息消失了,而且它運作得很好!

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

mime_magic.debug 預設是關閉的,但沒有這行它會失敗。我正在使用 PHP 5.2.5。
To Top