应使用pathinfo($filepath, PATHINFO_EXTENSION)安全提取后缀,它能正确处理带查询参数、锚点或目录名含点的路径;对URL需先parse_url()提取path再调用;多级扩展名默认返回最后一段,如需完整链须先取basename再正则匹配。

需要从PHP文件路径中准确提取后缀名,但直接用substr或strrchr容易在带查询参数、锚点或特殊字符的URL路径下出错,pathinfo函数能安全处理这些边界情况。
基础用法:用PATHINFO_EXTENSION提取后缀
调用pathinfo()并传入PATHINFO_EXTENSION常量,即可返回不含点号的纯后缀字符串。
这一步操作起来很简单,直接把文件路径传进去就行:pathinfo($filepath, PATHINFO_EXTENSION)。
注意:如果路径不含扩展名(如/home/user/config),该函数返回空字符串,不是false也不是null——这点和file_exists等函数行为不一致,后续判断要写=== ''而非=== false。
立即学习“PHP免费学习笔记(深入)”;
处理含查询参数或锚点的真实URL路径
当输入是类似https://example.com/script.php?v=1#section这样的完整URL时,pathinfo无法自动剥离协议、主机、查询串和锚点。
第一步:用parse_url()先拆解URL,取其中的path部分:$parsed = parse_url($url); $path = $parsed['path'] ?? '';
第二步:将提取出的$path传给pathinfo:pathinfo($path, PATHINFO_EXTENSION)。
如果不先parse_url就直接丢URL进去,pathinfo会把问号后面的内容当作文件名一部分,导致返回php?v=1#section这种错误结果——这不是bug,是它按“路径”语义解析的必然行为。
应对多级扩展名的特殊情况
某些场景下需区分archive.tar.gz这类双扩展名:用户可能想要gz,也可能想要tar.gz。
方法一:默认行为返回gz,因为pathinfo只认最后一个点之后的部分。
方法二:若需获取完整后缀链,得手动处理。先用pathinfo拿到basename,再用正则匹配所有点分隔的后缀段:preg_match('/\.([^.]+(?:\.[^.]+)*)$/', $basename, $matches),然后取$matches[1]。
【不要对原始路径直接正则匹配点号】,因为路径中可能含目录名带点(如/v1.2.3/release/),必须先用pathinfo提取basename再处理。
绕过pathinfo的三种替代方案对比
方法一:用strrpos + substr组合——$pos = strrpos($filename, '.'); echo $pos !== false ? substr($filename, $pos + 1) : '';。简单但无法识别config.这种末尾带点的合法文件名,会返回空而不是.。
方法二:用explode + end——end(explode('.', $filename))。更短,但遇到file..txt会返回txt而非txt(正确),而pathinfo返回txt;遇到.gitignore会返回空,pathinfo也返回空——行为一致,但explode在超长路径下性能略差。
方法三:用SplFileInfo——(new SplFileInfo($filepath))->getExtension()。功能等价于pathinfo(PATHINFO_EXTENSION),且对象化调用更易测试,但引入额外对象开销,对简单脚本略重。



















