在 PHP 開發中,正確識別檔案類型對安全性與功能實作至關重要。本文系統整理五種主流方法,從基本檔案資訊獲取到專業 MIME 偵測,並附上實戰代碼範例。
使用 fstat() 一次性獲取檔案完整統計資訊,避免重複系統呼叫:
$file = 'example.txt'; $handle = fopen($file, 'r'); $stat = fstat($handle); echo "檔名:".basename($file)."
"; echo "大小:".round($stat['size']/1024, 2)." KB
"; echo "最後存取:".date('Y-m-d H:i:s', $stat['atime'])."
"; echo "最後修改:".date('Y-m-d H:i:s', $stat['mtime'])."
"; fclose($handle);
echo mime_content_type('photo.gif'); // image/gif
echo mime_content_type('script.php'); // text/plain
注意:PHP 5.3.0 起棄用,需啟用 magic_mime 擴展才能使用。新專案不建議採用。
$finfo = finfo_open(FILEINFO_MIME_TYPE); $mime = finfo_file($finfo, $filename); finfo_close($finfo);
PHP 5.3+ 內建支援,無額外設定,回傳標準 MIME 類型(如 application/pdf),是現代專案首選。
$type = exif_imagetype($imagePath); // 回傳常數如 IMAGETYPE_JPEG $mime = image_type_to_mime_type($type); // 轉為 image/jpeg
需啟用 php_exif.dll 與 php_mbstring.dll。僅適用圖片,但準確度最高。
由瀏覽器根據副檔名判斷,不可信任,僅供參考。務必配合伺服端驗證。
讀取檔案前幾位元組,對照已知特徵碼:
$file = fopen($path, 'rb');
$header = fread($file, 2);
fclose($file);
$code = unpack('C2chars', $header);
$signature = $code['chars1'].$code['chars2'];
$types = [
255216 => 'jpg', // FF D8
7173 => 'gif', // 47 49
6677 => 'bmp', // 42 4D
13780 => 'png', // 89 50
7790 => 'exe', // 4D 5A
8297 => 'rar', // 52 61
];
echo $types[$signature] ?? 'unknown';
此法不依賴副檔名,可有效防止偽裝檔案上傳。
| 場景 | 推薦方法 | 備註 |
|---|---|---|
| 一般檔案 MIME 偵測 | Fileinfo (finfo_open) | 標準、可靠、無相依 |
| 圖片處理流程 | exif_imagetype + image_type_to_mime_type | 專業、支援多種圖片格式 |
| 上傳安全檢查 | Magic Bytes + Fileinfo 雙重驗證 | 防繞過、防偽裝 |
| 快速副檔名判斷 | pathinfo() + 白名單 | 僅作輔助,不可單獨使用 |
檔案類型識別是分層防禦的關鍵一環。建議採用 Fileinfo 作為主力,Magic Bytes 作為補充驗證,並嚴格限制允許上傳的 MIME 白名單。切勿單獨信任 $_FILES 或副檔名,以免造成安全漏洞。