最可靠的方法是用 getimagesize() 实际解析图像结构,因其可识别真实宽高和编码格式,而扩展名和 MIME 类型易被伪造;需配合文件存在性、可读性校验及 @ 抑制警告,并结合白名单类型判断与安全存储措施。

直接用 getimagesize() 最可靠,比检查扩展名或 MIME 类型更防伪。
为什么不能只看文件扩展名
扩展名完全由用户控制,test.php.jpg 或 shell.jpg 可能是恶意脚本。仅用 pathinfo($file, PATHINFO_EXTENSION) 判断等于开门揖盗。
- 攻击者可上传带 PHP 代码的 .jpg 文件,配合解析漏洞触发执行
-
mime_content_type()和finfo_file()依赖文件头,但部分非图片文件(如精心构造的 HTML)可能伪造头部骗过检测 -
getimagesize()会实际解析图像结构(宽高、编码格式),失败即说明不是有效图片
getimagesize() 的正确用法和容错处理
它在失败时返回 false,且会触发警告(warning),必须用 @ 抑制或提前校验文件存在性与可读性。
- 先确认
is_file($path) && is_readable($path),避免警告和错误 - 调用前加
@:$info = @getimagesize($path);,否则无效图片会报 warning - 成功时返回数组,
$info[2]是类型常量(如IMAGETYPE_JPEG),可进一步过滤支持的格式 - 注意:GIF 动图、WebP、AVIF 等较新格式需对应 PHP 版本支持(如 WebP 要 PHP 7.4+,AVIF 需 8.1+ 且 GD 启用 libavif)
示例:
诚客在线考试是由南宁诚客网络科技有限公司开发的一款手机移动端的答题网站软件,它应用广泛适合各种学校、培训班、教育机构、公司企业、事业单位、各种社会团体、银行证券等用于学生学习刷题、员工内部培训,学员考核、员工对公司制度政策的学习……可使用的题型有:单选题、多选题、判断题支持文字,图片,音频,视频、数学公式。可以设置考试时间,答题时间,考试次数,是否需要补考,是否可以看到自己成绩。练习模式,支持学生
立即学习“PHP免费学习笔记(深入)”;
if (is_file($path) && is_readable($path)) {
$info = @getimagesize($path);
if ($info && in_array($info[2], [IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_GIF])) {
// 是合法 JPG/PNG/GIF
}
}
GD 扩展未启用时的降级方案
若服务器没开 GD(extension=gd),getimagesize() 仍可用(它是独立函数,不依赖 GD),但某些图像类型(如 WebP)可能识别失败。此时可组合使用 finfo_open() 做辅助判断:
- 用
finfo_open(FILEINFO_MIME_TYPE)获取 MIME 类型,如image/jpeg - 但必须配合内容校验——仅靠 MIME 不安全,要限制为白名单类型且结合
getimagesize()主判 - 避免用
$_FILES['xxx']['type'],该字段由浏览器提供,完全不可信
真正关键的是:图片有效性 ≠ 安全性。即使 getimagesize() 通过,也要重命名存储、禁止执行权限、隔离上传目录。类型判断只是第一道过滤,不是保险柜。










