exifimagetype 函数可识别 gif、jpeg、png、bmp、tiff、swf、psd、jb2、jp2、jpc、jpx、swc、iff、wbmp、xbm 等格式,返回对应 imagetype* 常量;不支持 webp(php 7.1+ 且 libgd 启用时部分支持)、avif、heic、svg 等较新或非二进制图像格式。

exif_imagetype 函数能识别哪些图片类型
exif_imagetype 不是靠文件后缀或 MIME 类型判断,而是读取文件头部的 magic bytes。它只支持有限的几种格式,返回值是预定义常量(如 IMAGETYPE_JPEG、IMAGETYPE_PNG),不支持 WebP、AVIF、HEIC 等较新的格式。常见可识别类型包括:IMAGETYPE_GIF、IMAGETYPE_JPEG、IMAGETYPE_PNG、IMAGETYPE_BMP、IMAGETYPE_WEBP(PHP 7.1+ 才支持)。
注意:即使 PHP 版本 ≥7.1,exif_imagetype 对 WebP 的识别也依赖 libgd 是否启用 WebP 支持;某些精简编译的环境(如 Alpine + musl)可能实际返回 FALSE。
上传后立即调用 exif_imagetype 的正确姿势
必须传入**临时文件的本地路径**(即 $_FILES['xxx']['tmp_name']),不能传 URL、数据流(php://input)、或已移动后的路径。函数内部会 fopen 文件并读前 12 字节,因此路径必须可读且未被 move_uploaded_file 清理。
- ✅ 正确:在
move_uploaded_file前调用,参数为$_FILES['avatar']['tmp_name'] - ❌ 错误:传
$_FILES['avatar']['name'](这是原始文件名,不是路径) - ❌ 错误:传
$_POST['image_data'](base64 数据需先写入临时文件再检测) - ❌ 错误:在
move_uploaded_file后传目标路径但权限不对(如 web 用户无读权限)
示例:
if (!is_uploaded_file($_FILES['photo']['tmp_name'])) {
die('非法上传');
}
$imagetype = exif_imagetype($_FILES['photo']['tmp_name']);
if ($imagetype === false) {
die('无法识别图片格式');
}
为什么 exif_imagetype 返回 false 却没报错
返回 false 表示「无法识别」,不是「出错」——函数本身不会触发 warning 或 exception。常见原因有:
- 文件为空(
$_FILES['x']['size'] === 0) - 临时文件已被其他逻辑删除或
move_uploaded_file移走 - 文件头被篡改(比如用户把 .txt 改成 .jpg 后缀,但内容不是图片)
- PHP 编译时未启用 exif 扩展(检查
extension=exif是否在 php.ini 中启用,且php -m | grep exif有输出) - 文件大于
memory_limit?不,exif_imagetype只读前 12 字节,和内存限制无关
建议搭配 getimagesize 或 finfo_open 做二次验证,尤其对安全性要求高的场景(如头像上传)。
和 finfo_open 比,该选哪个
exif_imagetype 更轻量、更快,但识别范围窄;finfo_open 基于 libmagic,支持更多格式(含 WebP、SVG、ICO),且可识别 MIME 类型(如 image/svg+xml)。若只需基础 JPG/PNG/GIF 校验,exif_imagetype 足够;若需兼容现代格式或更准的 MIME,用 finfo_open。
关键区别:
-
exif_imagetype返回整数常量,需手动映射到扩展名或 MIME -
finfo_open(FILEINFO_MIME_TYPE)直接返回字符串如"image/jpeg" -
finfo_open需要确保fileinfo扩展启用,且 magic db 文件存在(通常默认 OK)
别忽略一点:exif_imagetype 对 SVG 文件完全无效(SVG 是 XML,无图片 magic bytes),而 finfo 能识别。如果业务允许上传 SVG,必须换方案。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











