pathinfo() 是提取文件扩展名最稳妥的方式,必须显式传入 PATHINFO_EXTENSION 参数,否则不返回 extension 键;它兼容多级扩展名、隐藏文件及跨平台路径,但返回值大小写与源一致,建议统一转小写比较。

用 pathinfo() 提取扩展名最稳妥
PHP 里想拿文件扩展名,pathinfo() 是官方推荐、兼容性最好、语义最清晰的方式。它不依赖字符串截取逻辑,能正确处理带点号的文件名(比如 archive.tar.gz),也避开大小写、路径分隔符等边缘问题。
常见错误是直接用 substr(strrchr($filename, '.'), 1) 或正则硬匹配,结果在 config.ini.bak、.gitignore、image.jpeg 这类文件上出错——前者漏掉隐藏文件,后者可能误判多级扩展名。
-
pathinfo($filename, PATHINFO_EXTENSION)返回小写扩展名(如jpg),不带点 - 对
.htaccess这类无扩展名文件,返回空字符串;对archive.tar.gz返回gz(只取最后一段) - 若需获取全部后缀(如
tar.gz),得自己解析pathinfo($filename, PATHINFO_FILENAME)和原始字符串,pathinfo()不支持
pathinfo() 的第二个参数必须显式传入
很多人写成 pathinfo($filename)['extension'],看似简洁,但 PHP 8.0+ 开始在未指定选项时默认只返回关联数组,且不含 extension 键——实际返回的是 dirname、basename、filename,**没有 extension**,导致 Notice 错误或空值。
这是最容易踩的坑:函数行为看似“智能”,实则严格依赖参数。不传 PATHINFO_EXTENSION,就别指望拿到扩展名。
立即学习“PHP免费学习笔记(深入)”;
- 正确写法:
pathinfo($filename, PATHINFO_EXTENSION) - 错误写法:
pathinfo($filename)['extension'](不可靠)、pathinfo($filename, -1)(非法参数) - 如果要同时取多个字段,用
pathinfo($filename)获取完整数组,再取键,但记得先判断键是否存在
Windows 路径和大小写不影响 pathinfo() 行为
pathinfo() 内部按 POSIX 规范解析路径分隔符,自动兼容 \ 和 /,所以传入 C:\Users\file.TXT 或 /var/www/file.txt 都能正确提取 TXT 或 txt(注意:返回值大小写与源字符串一致,不会自动转小写)。
但要注意:PHP 自身不校验文件是否存在,也不做大小写归一化。如果你依赖扩展名做类型判断(比如 if ($ext === 'jpg')),而用户上传了 IMG.JPG,就会失败。
- 建议统一转小写比较:
strtolower(pathinfo($filename, PATHINFO_EXTENSION)) === 'jpg' - 不要用
pathinfo()判断文件真实性——它纯字符串解析,pathinfo('fake.jpg', PATHINFO_EXTENSION)同样返回jpg - Windows 下反斜杠会被正常识别,无需预先
str_replace()替换
替代方案:explode() + end() 仅限简单场景
如果确定文件名格式极其干净(如 photo_123.jpg),且不处理隐藏文件、多点号名、Windows 路径,可以用 end(explode('.', $filename))。但它本质是字符串切片,没经过路径语义解析,风险高。
典型翻车现场:end(explode('.', '.bashrc')) 返回空;end(explode('.', 'a.b.c')) 返回 c(而非 b.c);end(explode('.', 'C:\path\to\file.png')) 在 Windows 上可能因反斜杠干扰返回 to\file.png。
- 仅建议用于临时脚本、已知输入格式的 CLI 工具
- Web 上传场景一律用
pathinfo(),哪怕多敲几个字符 - 如果必须用
explode(),至少加一层pathinfo($filename, PATHINFO_FILENAME)先剥离路径
pathinfo() 默认不返回它——这个参数不是可选,是必填。











