pathinfo()是PHP中唯一能准确提取文件后缀名的方案,它按POSIX规范语义解析路径,天然兼容多级扩展、隐藏文件、无扩展名、反斜杠路径及UTF-8中文名,且必须显式传入PATHINFO_EXTENSION参数才能获取扩展名。

当你需要在PHP中准确提取文件后缀名,比如验证上传文件类型、生成存储路径或判断MIME类型,直接用字符串函数硬切容易在.gitignore、archive.tar.gz、config.、C:\temp\log.txt这些场景翻车——pathinfo()专为路径解析而生,不依赖点号位置、不惧多级扩展、不care斜杠方向,才是唯一能稳住全场的方案。
pathinfo能天然避开字符串截取的全部坑
方法一:用substr + strrpos手动找最后一个点
这写法看着短,但漏掉basename()剥离路径就崩:/var/log/apache2.4/error.log会被误判为log,而不是真正的log;遇到.gitignore会返回gitignore(错),遇到README直接触发Warning(因为strrpos返回false)。
方法二:用end(explode('.', $filename))
完全无视路径结构,/home/user/file.tar.gz会被切成['/home/user/file', 'tar', 'gz'],取最后一段得gz——碰巧对了,但逻辑上根本没处理路径层级,属于侥幸过关。
方法三:用strrchr($filename, '.') . substr()
对以点开头的隐藏文件(如.htaccess)失效,strrchr返回完整字符串,substr截出来是taccess;对无点文件名(如Dockerfile)返回false,再substr就报Warning。
立即学习“PHP免费学习笔记(深入)”;
【pathinfo不解析路径也不依赖点位,它按POSIX规范识别“文件名主体+扩展名”结构,纯语义解析】
pathinfo对边界情况的处理是开箱即用的
第一步:传入archive.tar.gz → pathinfo($f, PATHINFO_EXTENSION)返回gz
第二步:传入.gitignore → 返回空字符串(不是false,不是null,是'',可直接empty()判断)
第三步:传入config. → 返回空字符串(符合POSIX定义:点结尾=无扩展名)
第四步:传入C:\Users\Report.xlsx → 返回xlsx(自动兼容反斜杠,无需str_replace)
所有这些,都不需要你写if-else补丁。而手动截取方案每一种都要额外加5行校验代码才能勉强跑通。
必须显式传参,否则拿不到扩展名
错误写法:$ext = pathinfo($filename)['extension'];
PHP 8.0+默认不返回extension键,数组里只有dirname、basename、filename——运行时触发Notice,变量为null。
正确写法:$ext = pathinfo($filename, PATHINFO_EXTENSION);
这个调用保证返回字符串,哪怕结果是空,类型也确定,不会引发类型警告或索引未定义错误。
【不传PATHINFO_EXTENSION参数,pathinfo就永远不会吐出extension】
中文文件名和大小写问题它也不甩锅
pathinfo('报表.xlsx', PATHINFO_EXTENSION) → xlsx
pathinfo('简历.PDF', PATHINFO_EXTENSION) → PDF(大小写与源一致)
它不依赖系统locale,不读取环境变量,纯字符串逐字节解析,UTF-8编码的中文文件名照常工作。
注意:若需统一比对,建议立刻接strtolower()——这不是pathinfo的缺陷,而是业务层该做的归一化。
上传场景下,务必先取$_FILES['file']['name'],再用pathinfo(basename($name), PATHINFO_EXTENSION),避免客户端伪造的路径干扰解析结果。



















