pathinfo 是 PHP 中最直接可靠获取文件后缀名的方式,能天然处理多级扩展名和边界情况;而 substr(strrchr()) 易在隐藏文件、无点名、路径含多点等场景出错。

pathinfo 是 PHP 中最直接、最可靠的方式获取文件后缀名,无需正则或字符串截取,且天然处理多级扩展名(如 .tar.gz)和边界情况(空扩展名、无点号、目录路径等)。
为什么不用 substr(strrchr($filename, '.'), 1)?
这种写法看似简洁,但容易在以下场景出错:
- 文件名以点开头但无扩展名(如
.gitignore),strrchr返回完整字符串,substr会截出gitignore(错误) - 文件名不含点(如
README),strrchr返回false,substr(false, 1)触发警告并返回空字符串 - 路径含多个点但非扩展名(如
/var/log/apache2.4/error.log),只取最后一个点后内容,误判为log而非真实扩展名log—— 表面碰巧对,实则逻辑脆弱
pathinfo 的正确调用方式与参数差异
必须显式传入 PATHINFO_EXTENSION,否则默认返回整个数组,浪费性能且易引发类型错误:
// ✅ 正确:只取扩展名,返回字符串(可能为空) $ext = pathinfo($filename, PATHINFO_EXTENSION); // ❌ 错误:返回关联数组,后续直接 echo 或比较会出问题 $info = pathinfo($filename); // ['dirname' => '...', 'basename' => '...', 'extension' => 'php', 'filename' => 'index'] $ext = $info['extension']; // 可行但冗余,且当文件无扩展名时 $info['extension'] 不存在,触发 notice
注意:pathinfo 对路径中的斜杠不敏感,pathinfo('a/b/c.txt', PATHINFO_EXTENSION) 和 pathinfo('c.txt', PATHINFO_EXTENSION) 结果一致。
立即学习“PHP免费学习笔记(深入)”;
处理多级扩展名(如 .tar.gz)的常见误解
pathinfo 默认只识别最后一个点后的部分为扩展名,即 archive.tar.gz → gz。若需获取全部扩展名(如 tar.gz),它本身不支持,需额外处理:
- 确认需求:绝大多数场景(MIME 判断、文件类型路由)只需主扩展名(
gz) - 如真需完整后缀,建议用
preg_match('/\.[^./]+(?:\.[^./]+)*$/', $filename, $matches)提取,但要小心路径末尾斜杠、隐藏文件等边界 - 不要强行用
pathinfo($filename, PATHINFO_FILENAME)套娃切割——pathinfo('a.tar.gz', PATHINFO_FILENAME)返回a.tar,再对其调用pathinfo仍得tar,无法还原tar.gz
真正容易被忽略的是:当 $filename 是目录路径(如 /home/user/docs/)或结尾带斜杠时,pathinfo 会返回空字符串作为扩展名——这不是 bug,是设计行为,因为目录没有扩展名。业务代码中若未预判此情况,可能导致空值参与后续判断而逻辑断裂。



















