pathinfo($filename, pathinfo_extension)最稳妥,因其基于内核路径语义解析,准确返回最后一段扩展名(如a.tar.gz→gz),且对无扩展名、隐藏文件、空字符串均安全返回空,不触发警告;而substr+strrchr等字符串方法在边界场景易出错。

用 pathinfo() 最稳妥
直接取文件名后缀,pathinfo() 是 PHP 原生最可靠的方式,它能正确处理带多个点、末尾有空格、无扩展名等边界情况。
别用 substr(strrchr($filename, '.'), 1) 这类手动截取——遇到 archive.tar.gz 或 readme. 就会出错。
实操建议:
- 始终传入
PATHINFO_EXTENSION第二个参数:pathinfo($filename, PATHINFO_EXTENSION) - 对用户上传的文件名,先
trim()再调用,避免末尾空格干扰判断 - 返回值可能是空字符串(如
file或.gitignore),需显式判断=== ''而非用empty() - 不区分大小写?PHP 不自动转换,要统一格式请自己
strtolower()
strrpos() + substr() 手动切更轻量
如果只处理简单场景(比如已知文件名规范、性能敏感且确定不会出现 .tar.gz 类型),可以跳过 pathinfo() 的开销。
常见错误现象:用 strpos() 找第一个点,结果 image.jpeg 取成 jpeg 没问题,但 my.config.json 就错成 config.json。
正确写法要点:
- 必须用
strrpos()找最后一个点的位置 - 检查返回值是否为
false(没找到点),再做substr() - 示例:
$ext = (false !== $pos = strrpos($filename, '.')) ? substr($filename, $pos + 1) : ''; - 注意:这个逻辑仍无法区分
.htaccess(无扩展名)和file.(空扩展名)
上传文件时别只信客户端传的 name
浏览器提交的 $_FILES['file']['name'] 可被任意伪造,扩展名不能作为安全依据。比如用户把恶意脚本命名为 shell.jpg.php,前端显示为 JPG,但服务器若只看后缀就放行,可能执行代码。
实操建议:
- 用
finfo_open(FILEINFO_MIME_TYPE)检查真实 MIME 类型 - 白名单过滤扩展名,而非黑名单(比如只允许
['jpg', 'png', 'pdf']) - 保存时强制重命名,丢弃原始
name,避免路径遍历或特殊字符问题 - Web 服务器配置也要限制执行权限(如 Nginx 对
/uploads/禁用.php解析)
注意 PATHINFO_EXTENSION 在 Windows 和 Linux 下行为一致
有人担心跨平台兼容性,其实不用——pathinfo() 对斜杠/反斜杠都识别,且扩展名提取逻辑与系统无关。真正要注意的是路径分隔符本身,比如拼接路径时用 DIRECTORY_SEPARATOR,但提取扩展名这一步完全不受影响。
容易被忽略的地方:当文件名是绝对路径(如 /var/www/file.txt)或含 URL 查询参数(如 photo.jpg?size=large)时,pathinfo() 仍只解析路径部分,不会误吞 ?size=large;但如果整个字符串来自不可信来源(比如 URL 参数里传了完整 URL),得先 parse_url() 提取 path 段再处理。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











