getimagesize() 无法识别 pdf 文件,因其仅支持图像类 mime 类型(如 image/jpeg),而 pdf 真实类型为 application/pdf,调用后直接返回 false 或警告;应改用 finfo_open() 基于魔数检测真实 mime 类型,并结合扩展名双重校验确保安全。

为什么 getimagesize() 识别不了 PDF 文件
getimagesize() 是 PHP 中常用来验证图像文件的函数,但它只支持图像类 MIME 类型(如 image/jpeg、image/png)。PDF 文件虽然可能以 .pdf 结尾,但其真实类型是 application/pdf,getimagesize() 遇到它会直接返回 false 或触发警告,而不是报错。很多开发者误把它当“通用类型检测工具”,结果导致 PDF 被当成非法文件拒绝上传。
用 finfo_open() 检测真实 MIME 类型才可靠
PHP 5.3+ 自带 finfo_open(),它基于文件内容(magic bytes)识别类型,不受扩展名干扰,对 PDF 支持稳定。必须配合临时文件路径($_FILES['file']['tmp_name'])使用,不能传原始文件名。
- 确保
fileinfo扩展已启用(phpinfo()查看是否有 “fileinfo” 模块) - 不要用
$_FILES['file']['type']—— 这个值由浏览器提供,完全不可信,可被任意伪造 - 检测后需白名单校验:只允许
application/pdf,不接受application/x-pdf等非标准变体
示例代码片段:
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $_FILES['file']['tmp_name']);
finfo_close($finfo);
if ($mimeType !== 'application/pdf') {
die('仅支持 PDF 文件');
}
上传失败错误码 7(UPLOAD_ERR_CANT_WRITE)常被误判为类型问题
用户上传 PDF 时提示“类型错误”,但实际是 $_FILES['file']['error'] === UPLOAD_ERR_CANT_WRITE(错误码 7),说明 PHP 写入临时文件失败。这和 MIME 检测无关,但现象类似:文件没存进 tmp_name,后续所有检测都失效。
- 常见原因:系统临时目录(
/tmp或C:\Windows\Temp)空间不足或权限不对 - 检查
upload_tmp_dir是否显式配置且目录可写;未配置时依赖系统默认路径,容易出问题 - 注意:这个错误发生时,
$_FILES['file']['tmp_name']为空或不存在,finfo_file()会报 warning 并返回false,容易被当成“类型不匹配”
扩展名 + MIME 双重校验才是生产环境底线
只靠 MIME 检测仍有风险:极少数 PDF 文件头被裁剪或损坏,finfo 可能误判为 application/octet-stream;而只靠扩展名又太脆弱。二者结合才是稳妥做法。
- 先检查
pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION)是否为pdf(忽略大小写) - 再用
finfo_open()验证真实 MIME,两者都通过才放行 - 注意:不要用
strtolower()处理整个文件名,有些系统对大小写敏感;只处理扩展名部分即可 - 如果业务允许,可加一层
readfile($_FILES['file']['tmp_name'])后用pdfinfo(命令行)做二次确认,但会增加延迟和依赖
最易被忽略的一点:所有检测必须在 UPLOAD_ERR_OK 为真之后执行。否则你正在检测一个根本没上传成功的空文件。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











