最稳方式是pathinfo($filename, pathinfo_extension),它专为提取扩展名设计,兼容多级扩展名、跨平台路径及隐藏文件,只返回最后一个点后的纯后缀(不含点),需配合is_string()校验和大小写归一化使用。

当你需要从用户上传的文件名中提取扩展名、目录或主体名称时,直接用 substr + strrpos 截取字符串容易在中文名、多点名、隐藏文件或空后缀场景下返回错误结果甚至触发 PHP 警告,而 pathinfo() 是 PHP 内置的路径解析函数,它按文件系统语义而非字节位置工作,天然规避多数边界陷阱。
处理多点文件名时 pathinfo 不会误判
比如文件名是 archive.tar.gz,手动用 strrpos($name, '.') + 1 截取会得到 gz,看似正确——但若文件名是 config.backup.old,同样逻辑却会返回 old,而实际业务中你可能想识别的是 old 还是 backup.old?pathinfo 的 PATHINFO_EXTENSION 永远只取最后一个点之后的内容,这是设计契约,不是巧合。
这一步操作起来很简单,直接调用 pathinfo($filename, PATHINFO_EXTENSION) 就行。
【PATHINFO_EXTENSION 只返回最后一个点后的纯后缀,不含点】
面对隐藏文件和空后缀,pathinfo 返回可预测值
手动截取遇到 .gitignore 或 log. 时极易出错:strrchr() 在前者返回完整字符串,截掉点后变成 gitignore;后者因末尾是点,strrpos() 找不到有效位置,返回 false,substr() 报 Warning 并返回空。
pathinfo 则明确:对 .gitignore 返回空字符串,对 log. 也返回空字符串——两者都表示“无有效扩展名”,语义统一,便于后续判断。
注意:传入空字符串或非字符串类型会触发警告,务必先做 is_string($filename) && $filename !== '' 校验。
中文与多字节字符环境下不截断
当用户上传文件名为 2012年《牛马大赛》竞赛冠军名单.docx,且服务器 locale 为 C(默认)时,基于字节扫描的手动截取函数可能把中文括号的第二字节误认为路径分隔符 /(ASCII 0x2F),导致 basename 提前截断,生成 牛马大赛》竞赛冠军名单.docx 这类损坏名称。
pathinfo 在正确设置 locale(如 setlocale(LC_ALL, 'zh_CN.UTF-8'))的前提下,按字符而非字节解析,能完整保留中文和符号。
【未设置 UTF-8 locale 时,pathinfo 对含中文路径仍可能按字节截断,必须提前 setlocale】
自动适配不同路径格式,无需额外清洗
第一步:传入 C:\Users\test\photo.PNG → pathinfo 自动识别反斜杠为分隔符,返回 extension 为 PNG;
第二步:传入 /var/www/uploads/report_v1.2.pdf → 正常提取 pdf;
第三步:传入 image.jpeg.bak(无路径)→ 依然准确返回 bak,不依赖是否含斜杠。
手动方案必须先用 basename() 剥离路径,再找点位,两步缺一不可;pathinfo 一步到位,且内部已处理 Windows/Linux/URL 风格路径的兼容逻辑。











