finfo_file 是 php 中最可靠的文件真实类型识别方法,需启用 fileinfo 扩展,用 finfo_open(fileinfo_mime_type) 创建句柄,再以绝对路径调用 finfo_file 获取 mime 类型,最后映射为扩展名并释放资源。

要准确识别上传文件或本地二进制文件的真实类型(绕过伪造的扩展名),必须依赖文件内容而非文件名,finfo_file 是 PHP 提供的最可靠手段之一。
启用 fileinfo 扩展并创建资源
确认 php.ini 中已启用 extension=fileinfo(Windows 下为 php_fileinfo.dll,Linux/macOS 通常默认编译进核心),未启用会导致 finfo_open 返回 false。
调用 finfo_open(FILEINFO_MIME_TYPE) 创建资源句柄,【必须传入 FILEINFO_MIME_TYPE 或 FILEINFO_EXTENSION,否则可能返回空字符串】。
用 finfo_file 读取文件真实 MIME 类型
将文件绝对路径传给 finfo_file,例如 finfo_file($finfo, '/tmp/uploaded.bin'),返回类似 'image/jpeg' 或 'application/pdf' 的 MIME 字符串。
注意:路径必须可读,相对路径易因工作目录变化失效;若传入不存在的文件,函数返回 false 并触发 E_WARNING。
从 MIME 类型映射到常用后缀
PHP 不内置 MIME 到扩展名的转换表,需手动建立映射关系。常见做法如下:
方法一:用 switch 匹配关键 MIME 类型
switch ($mime) { case 'image/jpeg': $ext = 'jpg'; break; case 'image/png': $ext = 'png'; break; case 'application/pdf': $ext = 'pdf'; break; default: $ext = 'bin'; }
方法二:使用关联数组查表(更易维护)
$mimeToExt = ['image/jpeg'=>'jpg', 'image/png'=>'png', 'text/plain'=>'txt', 'application/msword'=>'doc']; $ext = $mimeToExt[$mime] ?? 'dat';
方法三:调用 finfo_file($finfo, $file, FILEINFO_EXTENSION),直接获取扩展名(仅限 PHP 7.2+,且返回值含空格和分号,如 "jpg; ",需 trim() 和 explode(';', …)[0] 处理)。
完整安全调用流程
第一步:检查 fileinfo 是否可用 → if (!extension_loaded('fileinfo')) { throw new RuntimeException('fileinfo extension not loaded'); }
第二步:初始化 finfo 资源 → $finfo = finfo_open(FILEINFO_MIME_TYPE); if (!$finfo) { throw new RuntimeException('finfo_open failed'); }
第三步:获取 MIME → $mime = finfo_file($finfo, $filepath); if ($mime === false) { throw new InvalidArgumentException("Unable to detect mime for {$filepath}"); }
第四步:映射后缀 → $ext = match($mime) { 'image/gif' => 'gif', 'application/zip' => 'zip', 'audio/mpeg' => 'mp3', default => 'bin' };
第五步:清理资源 → finfo_close($finfo);
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











