簡體   English   中英

如何使用 PHP 找到文件的 MIME 類型?

[英]How do I find the MIME type of a file with PHP?

我有一個index.php文件,它必須處理許多不同的文件類型。 如何根據REQUEST_URI猜測文件類型?

如果我請求http://site/image.jpg ,並且所有請求都通過index.php重定向,看起來像這樣

<?php
   include('/www/site'.$_SERVER['REQUEST_URI']);
?>

我將如何使它正常工作?

我應該根據請求的文件的擴展名進行測試,還是有辦法獲取文件類型?

如果您確定您只使用圖像,您可以查看exif_imagetype() PHP 函數,該函數嘗試返回圖像 MIME 類型。

如果您不介意外部依賴,您還可以查看出色的getID3庫,它可以確定許多不同文件類型的 MIME 類型。

最后,您可以查看mime_content_type()函數 - 但它已被Fileinfo PECL 擴展所棄用。

mime_content_type()已被棄用,因此您將無法指望它在未來工作。 有一個“fileinfo”PECL 擴展,但我還沒有聽說過它的好消息。

如果您在類似 Unix 的服務器上運行,您可以執行以下操作,這對我來說效果很好:

$file = escapeshellarg($filename);
$mime = shell_exec("file -bi " . $file);
$filename should probably include the absolute path.
function get_mime($file) {
  if (function_exists("finfo_file")) {
    $finfo = finfo_open(FILEINFO_MIME_TYPE); // Return MIME type a la the 'mimetype' extension
    $mime = finfo_file($finfo, $file);
    finfo_close($finfo);
    return $mime;
  } else if (function_exists("mime_content_type")) {
    return mime_content_type($file);
  } else if (!stristr(ini_get("disable_functions"), "shell_exec")) {
    // http://stackoverflow.com/a/134930/1593459
    $file = escapeshellarg($file);
    $mime = shell_exec("file -bi " . $file);
    return $mime;
  } else {
    return false;
  }
}

對我來說,這些都不起作用—— mime_content_type已被棄用, finfo未安裝,並且shell_exec是不允許的。

實際上,我厭倦了 PHP 中缺乏標准的 MIME 嗅探方法。 安裝文件信息...使用不推薦使用的功能...哦,這些工作,但僅適用於圖像! 我厭倦了它,所以我做了一些研究並找到了WHATWG MIME 嗅探規范——不過我相信這仍然是一個草案規范。

無論如何,使用這個規范,我能夠在 PHP 中實現 MIME 嗅探器。 性能不是問題。 事實上,在我簡陋的機器上,我能夠在 PHP 超時之前打開和嗅探數千個文件。

這是MimeReader 類

require_once("MimeReader.php");

$mime = new MimeReader(<YOUR FILE PATH>);
$mime_type_string = $mime->getType();     // "image/jpeg", etc.

如果您只使用圖像並且需要 MIME 類型(例如,對於標題),那么這是最快和最直接的答案:

$file = 'path/to/image.jpg';
$image_mime = image_type_to_mime_type(exif_imagetype($file));

即使您重命名圖像文件,它也會輸出真正的圖像 MIME 類型。

根據 PHP 手冊, finfo-file函數是最好的方法。 但是,您需要安裝FileInfo PECL 擴展。

如果擴展名不是一個選項,您可以使用過時的mime_content_type函數。

mime_content_type()似乎是要走的路,盡管之前的評論說它已被棄用。 根據http://php.net/manual/en/function.mime-content-type.php ,它不是——或者至少mime_content_type()的這種化身沒有被棄用。 它是 FileInfo 擴展的一部分,但 PHP 文檔現在告訴我們,它從 PHP 5.3.0 開始默認啟用。

從 PHP 5.3 開始,您可以使用 finfo 來完成此操作:

<?php
$info = new finfo(FILEINFO_MIME_TYPE);
echo $info->file('myImage.jpg');
// prints "image/jpeg"

FILEINFO_MIME_TYPE 標志是可選的; 沒有它,你會得到一些文件的更詳細的字符串; (顯然某些圖像類型會返回大小和顏色深度信息)。 使用 FILEINFO_MIME 標志返回 mime 類型和編碼(如果可用)(例如 image/png;charset=binary 或 text/x-php;charset=us-ascii)。 有關更多信息,請參閱此站點

我沒用過,但是有一個PECL 擴展來獲取文件的 MIME 類型。 它的官方文檔在手冊中。

根據您的目的,文件擴展名可能沒問題,但它不是非常可靠,因為它很容易更改。

如果您只處理圖像,則可以使用[getimagesize()][1]函數,該函數包含有關圖像的各種信息,包括類型。

更通用的方法是使用來自PECL的 FileInfo 擴展。

有些人對該擴展有嚴重的抱怨......因此,如果您遇到嚴重問題或由於某種原因無法安裝擴展,您可能需要查看已棄用的函數mime_content_type()

如果你運行 Linux 並且有擴展,你可以簡單地通過創建一個哈希數組從 /etc/mime.types 讀取 MIME 類型。 然后,您可以將其存儲在內存中,並通過數組鍵簡單地調用 MIME :)

/**
 * Helper function to extract all mime types from the default Linux /etc/mime.types
 */
function get_mime_types() {
    $mime_types = array();
    if (
        file_exists('/etc/mime.types') &&
        ($fh = fopen('/etc/mime.types', 'r')) !== false
    ) {
        while (($line = fgets($fh)) !== false) {
            if (!trim($line) || substr($line, 0, 1) === '#') continue;
            $mime_type = preg_split('/\t+/', rtrim($line));
            if (
                is_array($mime_type) &&
                isset($mime_type[0]) && $mime_type[0] &&
                isset($mime_type[1]) && $mime_type[1]
            ) {
                foreach (explode(' ', $mime_type[1]) as $ext) {
                    $mime_types[$ext] = $mime_type[0];
                }
            }
        }
        fclose($fh);
    }
    return $mime_types;
}

您的服務器上任何文件的 MIME 類型都可以通過以下方式獲得:

<?php
  function get_mime($file_path){
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $type  = $finfo->file(file_path);
  }

  $mime = get_mime('path/to/file.ext');

我使用來自http://php.net/manual/de/function.mime-content-type.php @''john dot howard at prismmg dot com 26-Oct-2009 03:43' 的用戶函數得到了非常好的結果'

function get_mime_type($filename, $mimePath = '../etc') { ...

它不使用finfoexec或已棄用的函數。

它也適用於遠程資源!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM