PHP的fileinfo函数识别MIME类型是读文件内容还是仅校验扩展名?
解答
PHP识别MIME的逻辑
你调用的finfo_file是基于libmagic库实现的,完全不参考文件后缀、也不使用HTTP请求上报的文件类型,只会读取文件头部的二进制特征(魔数)判断格式,本身就是为了避免篡改后缀伪造文件类型的问题。
你在$_FILES里拿到的浏览器上报的文件类型完全不可靠,是浏览器仅根据本地文件后缀猜测的,所以和finfo的识别结果出现差异非常正常。
同后缀MP4识别结果不一致的原因
MP4格式本身就是从QuickTime容器格式衍生而来,两者的文件头特征高度同源,都是以ftyp段作为开头标识,出现识别偏差的核心原因有两个:
- 你的PHP7.4环境对应的系统
libmagic版本偏旧,特征匹配规则优先级有问题:部分正常MP4的ftyp头的兼容品牌字段包含QuickTime的qt标识,旧版规则会优先匹配到video/quicktime而不是video/mp4 - 少数特殊压制的MP4文件,
ftyp头的主品牌字段没有使用标准MP4标识(mp41/mp42/iso2等),特征匹配时更符合旧版libmagic定义的QuickTime格式规则
修复建议
- 优先升级服务器的
libmagic依赖包,新版特征库对MP4和QuickTime的区分准确率提升非常明显 - 如果业务侧确认这类被误判的文件都是可正常播放的MP4,可直接将
video/quicktime加入上传白名单,额外补充一层简单的ftyp头校验即可:读取文件前16字节,确认包含MP4相关标识就能排除真实的QuickTime文件
内容的提问来源于stack exchange,提问作者Lambda
相关产品推荐
相关产品推荐

