应使用pathinfo($filename, pathinfo_extension)获取小写扩展名,它自动忽略路径、统一转小写且正确处理多点名和隐藏文件;避免explode或strrpos等手动解析方法,并需先用basename清洗路径、再用mb_strtolower转小写。

在Windows、Linux或macOS服务器上处理用户上传的文件时,必须确保获取后缀名的代码不因路径分隔符差异、大小写敏感性或隐藏文件命名规则而失效——比如.htaccess在Linux下被识别为扩展名htaccess,而C:\tmp\file.TXT在Windows中若用字符串截取可能返回大写TXT,导致后续MIME校验失败。
用pathinfo()配合PATHINFO_EXTENSION常量获取小写扩展名
这一步最稳妥,直接调用PHP内置函数,无需手动解析路径分隔符或点号位置。
执行pathinfo($filename, PATHINFO_EXTENSION),它自动忽略目录部分,只基于最后一个点(.)之后的内容提取扩展名,并统一转为小写。
例如:pathinfo('dir/sub/file.TXT', PATHINFO_EXTENSION) → 返回txt;pathinfo('/var/www/.env', PATHINFO_EXTENSION) → 返回env;pathinfo('archive.tar.gz', PATHINFO_EXTENSION) → 返回gz(不是tar.gz)。
【PATHINFO_EXTENSION是唯一能正确处理多点文件名和隐藏文件的官方方式】
避免使用explode('.',$filename)类方法
方法一:用end(explode('.', $filename))看似简洁,但遇到无扩展名文件(如README)、纯点开头文件(如.gitignore)或含路径分隔符的完整URL(如https://a.b/c.jpg)时,会返回空、gitignore或https://a.b/c——完全不可控。
方法二:用array_pop(explode('.', $filename))本质同上,且explode在空字符串或全点字符串(如..)下会返回空数组,array_pop返回NULL,触发Notice警告。
方法三:用strrpos + substr组合虽比explode稍稳,但若文件名不含点(如Makefile),strrpos返回false,substr($s, false + 1)等价于substr($s, 0),直接返回整个文件名——这会把Makefile误判为扩展名Makefile。
对上传文件名做预清洗再提取扩展名
第一步:从$_FILES['file']['name']拿到原始文件名后,先用basename()剥离可能存在的恶意路径(如../../etc/passwd.jpg)。
第二步:用mb_strtolower()统一转为小写,避免Linux下JPG与jpg被当作不同类型处理。
第三步:调用pathinfo($clean_name, PATHINFO_EXTENSION)获取最终扩展名。
示例代码链:$raw = $_FILES['upload']['name']; $safe = basename($raw); $lower = mb_strtolower($safe); $ext = pathinfo($lower, PATHINFO_EXTENSION);
注意:mb_strtolower()需启用mbstring扩展,否则用strtolower()替代——但后者不支持UTF-8多字节字符,若上传文件名为中文+英文混合(如测试报告.PDF),strtolower可能破坏中文部分,导致pathinfo解析异常。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











