PHP处理同名上传文件时,先用pathinfo()提取扩展名,再通过递增序号法(如“report_1.pdf”)或时间戳+随机数法生成唯一文件名,确保不覆盖原有文件。

当用户上传多个同名文件(如都叫“report.pdf”)时,PHP需要自动提取文件扩展名,并为重复文件添加序号后缀(如“report_1.pdf”),避免覆盖原有文件。
提取文件后缀名
使用 pathinfo() 函数获取扩展名,它比 substr(strrchr()) 更可靠,能正确处理带点的文件名(如 “archive.tar.gz”)。
$ext = pathinfo($filename, PATHINFO_EXTENSION);
注意:如果文件名以点开头(如 ".htaccess"),PATHINFO_EXTENSION 会返回空字符串。此时需用 strrpos() 手动判断——但本场景中用户上传文件通常有明确后缀,暂不处理该边缘情况。
立即学习“PHP免费学习笔记(深入)”;
检查目标文件是否已存在
在重命名前,必须确认新文件名是否已被占用,否则仍会覆盖。
先构造基础目标路径:$target = $upload_dir . '/' . $basename . '.' . $ext;
用 file_exists($target) 判断是否存在。若存在,进入重命名逻辑;若不存在,直接保存即可。
自动生成不重复的文件名
方法一:递增序号法(推荐)
① 初始化计数器:$counter = 1;
② 构造候选名称:$candidate = $upload_dir . '/' . $basename . '_' . $counter . '.' . $ext;
③ 循环检测:while (file_exists($candidate)) { $counter++; $candidate = $upload_dir . '/' . $basename . '_' . $counter . '.' . $ext; }
这一步必须执行完循环再跳出,否则可能生成仍冲突的文件名。循环结束时,【$candidate 就是最终可用的唯一路径】。
方法二:时间戳+随机数法(适合高并发)
直接拼接毫秒级时间戳与4位随机数:$suffix = round(microtime(true) * 1000) . '_' . str_pad(rand(0, 9999), 4, '0', STR_PAD_LEFT);
然后组合:$target = $upload_dir . '/' . $basename . '_' . $suffix . '.' . $ext;
此方法几乎不会碰撞,但文件名不可读,调试时不易追溯原始名称。



















