最可靠方式是用 pathinfo($_FILES'file') 获取数组,从中提取 filename 和 extension 键;需先判空并转小写 extension 以校验后缀,避免 explode 或 strrchr 等不健壮方法。

用 pathinfo 提取 $_FILES['file']['name'] 的原始文件名和后缀最可靠
直接读 $_FILES['file']['name'] 得到的是客户端上传时的完整文件名(如 report_v2(最新).pdf),但不能直接拆出“不带扩展名的原始名”或“真实后缀”。pathinfo 是 PHP 原生、安全、无需正则的解析方式,比 substr + strrpos 更健壮。
注意:必须作用于 $_FILES['xxx']['name'] 字符串本身,而不是临时路径 tmp_name —— 后者是服务器端随机生成的,与原始名称无关。
pathinfo 返回数组各键含义与常见误用
pathinfo 默认返回关联数组,常用键有:dirname(这里恒为 '.')、basename(含扩展名的完整文件名)、filename(PHP 5.2+ 才有,不含扩展名)、extension(小写后缀,不含点)。
-
filename不是“去掉后缀的原始名”的万能解:遇到多点文件名(如archive.tar.gz)时,它只截掉最后一个点后的部分,结果是archive.tar,而非预期的archive -
extension总是小写,但客户端可能传.PDF或.Pdf,若需严格校验后缀,应统一转小写再比对 - 不要用
PATHINFO_BASENAME参数去“单独取 basename”,因为$_FILES['x']['name']本来就没有路径,basename和原始值一样
实操:安全获取原始名与后缀的推荐写法
以下代码片段可直接复用,已规避空文件、无后缀、多点名等边界情况:
$uploaded_name = $_FILES['avatar']['name'] ?? '';
if (!$uploaded_name) {
// 文件未上传或为空,跳过处理
}
$info = pathinfo($uploaded_name);
$original_name = $info['filename'] ?? '';
$ext = strtolower($info['extension'] ?? '');
// 验证是否真有后缀(防止上传 test. 这类边缘名)
if (empty($ext)) {
// 可拒绝、可设默认后缀、也可保留原名(但存储时需加后缀避免 web 服务器误判)
}
关键点:
- 始终先判断
$_FILES['x']['name']是否非空,否则pathinfo('')返回空数组,取['filename']会触发 notice - 用
?? ''防止未定义索引警告;strtolower统一后缀大小写便于白名单校验(如in_array($ext, ['jpg', 'png', 'pdf'])) - 不建议用
pathinfo($uploaded_name, PATHINFO_FILENAME)单独调用——它在空字符串时返回false,不如一次取全量数组稳妥
为什么不用 explode('.', $name) 或 strrchr?
这些写法在真实场景中容易翻车:
-
explode('.', $name):遇到my.file.name.txt会得到['my','file','name','txt'],取最后一个元素看似合理,但若用户上传resume.(结尾带点),结果是空字符串;更糟的是.htaccess这种以点开头的文件,explode后第一个元素就是空 -
strrchr($name, '.'):返回从最后一个点开始的子串(含点),还得ltrim去点,且对无点文件返回false,需要额外判断 - 两者都无法区分
image.jpeg和image.JPEG,而pathinfo的extension键天然小写,省去一步转换
真正麻烦的不是解析名字,而是后续怎么用——比如存储时要不要保留原始名、是否要重命名防冲突、中文名在不同系统下是否乱码。这些都得在拿到 pathinfo 结果后再决策,别让解析逻辑和业务逻辑混在一起。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











