本文目录导读:

- finfo_file() - 最推荐的方法(PHP 5.3+)
- mime_content_type() - 简单但不够准确
- getimagesize() - 仅限图片文件
- 手动检测文件扩展名(最不推荐但最快速)
- 检查函数是否可用
- 处理上传文件
- 完整的封装函数
- 重要提示
在 PHP 中检测 MIME 类型有多种方法,以下是几种常见的方式:
finfo_file() - 最推荐的方法(PHP 5.3+)
// 使用 finfo 扩展(Fileinfo) $file = '/path/to/your/file.jpg'; // 创建 finfo 实例 $finfo = new finfo(FILEINFO_MIME_TYPE); // 获取 MIME 类型 $mimeType = $finfo->file($file); echo $mimeType; // 输出: image/jpeg
使用 FILEINFO_MIME 获取完整信息:
$finfo = new finfo(FILEINFO_MIME); $mime = $finfo->file($file); echo $mime; // 输出: image/jpeg; charset=binary
mime_content_type() - 简单但不够准确
// 传统的函数(不推荐在生产环境使用) $file = '/path/to/your/file.jpg'; $mimeType = mime_content_type($file); echo $mimeType; // 可能输出: image/jpeg
getimagesize() - 仅限图片文件
$file = '/path/to/your/image.jpg';
$imageInfo = getimagesize($file);
if ($imageInfo !== false) {
echo $imageInfo['mime']; // 输出: image/jpeg
} else {
echo '不是有效的图片文件';
}
手动检测文件扩展名(最不推荐但最快速)
function getMimeByExtension($filename) {
$mimeTypes = [
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
'pdf' => 'application/pdf',
'txt' => 'text/plain',
'html' => 'text/html',
// ... 更多类型
];
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
return isset($mimeTypes[$ext]) ? $mimeTypes[$ext] : 'application/octet-stream';
}
检查函数是否可用
// 检查 finfo 扩展是否可用
if (class_exists('finfo')) {
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($file);
} elseif (function_exists('mime_content_type')) {
$mime = mime_content_type($file);
} else {
// 最后的备选方案
$mime = 'application/octet-stream';
}
处理上传文件
if ($_FILES['userfile']['error'] === UPLOAD_ERR_OK) {
$uploadedFile = $_FILES['userfile']['tmp_name'];
// 使用 finfo 检测
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mimeType = $finfo->file($uploadedFile);
// 验证是否允许的文件类型
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
if (in_array($mimeType, $allowedTypes)) {
echo "文件类型允许: $mimeType";
} else {
echo "文件类型不允许: $mimeType";
}
}
完整的封装函数
function detectMimeType($filepath) {
if (!file_exists($filepath)) {
throw new Exception('文件不存在');
}
// 首选 finfo
if (class_exists('finfo')) {
$finfo = new finfo(FILEINFO_MIME_TYPE);
return $finfo->file($filepath);
}
// 备选方案
if (function_exists('mime_content_type')) {
return mime_content_type($filepath);
}
// 最后通过扩展名判断
$ext = strtolower(pathinfo($filepath, PATHINFO_EXTENSION));
$mimeMap = [
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'png' => 'image/png',
// 添加更多映射...
];
return isset($mimeMap[$ext]) ? $mimeMap[$ext] : 'application/octet-stream';
}
重要提示
- 安全性:MIME 检测不是安全验证,攻击者可以伪造 MIME 类型
- 性能:
finfo比mime_content_type更准确但稍慢 - 文件上传:最好结合文件大小、内容检查等多重验证
- PHP 版本:确保 PHP >= 5.3 以使用
finfo类
推荐使用 finfo 方法,因为它基于文件内容检测,比扩展名更可靠。