finfo_file() 是判断文件真实类型的最可靠方式,基于魔数识别,需启用 fileinfo 扩展并使用 fileinfo_mime_type 模式,检查 application/zip 等 mime 类型,避免依赖扩展名或废弃的 mime_content_type()。
用 finfo_file() 判断文件真实类型最可靠
仅靠扩展名(如 .zip、.rar)判断是否为压缩包完全不可信——用户可随意改名,甚至上传伪造的 report.pdf.zip 实际是木马。PHP 的 finfo_file() 基于文件魔数(magic bytes)识别真实格式,是唯一推荐方式。
实操要点:
- 确保
fileinfo扩展已启用(php -m | grep fileinfo验证) - 使用
FILEINFO_MIME_TYPE模式,避免返回冗长的 MIME 描述 - 对常见压缩格式,检查返回值是否匹配:
application/zip、application/x-rar-compressed、application/x-7z-compressed、application/gzip、application/x-bzip2 - 注意:某些 tar 包(未压缩)返回
application/x-tar,不属于“压缩包”,需按需排除
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, '/path/to/file');
finfo_close($finfo);
if (in_array($mimeType, [
'application/zip',
'application/x-rar-compressed',
'application/x-7z-compressed',
'application/gzip',
'application/x-bzip2'
])) {
// 确认为压缩包
}
为什么不用 mime_content_type()?
mime_content_type() 是 finfo_file() 的旧版封装,底层调用相同逻辑,但存在两个硬伤:
- PHP 8.0+ 已废弃,未来版本会移除
- 无法自定义 magic 数据库路径,遇到非标准压缩格式(如某些自定义加密归档)时识别率更低
- 不支持
FILEINFO_MIME_TYPE以外的精细控制,比如跳过文本编码检测
直接替换为 finfo_file() 几乎零成本,且兼容 PHP 5.3+ 所有版本。
立即学习“PHP免费学习笔记(深入)”;