发布于2026-07-09 阅读(0)
扫一扫,手机访问
文件上传时的文件名冲突,看起来是个小问题,但真遇上并发请求或者重复上传同一张图,就会发现随手拼的uniqid()或时间戳根本不够用——两个请求几乎同时进来,文件名一模一样,后传的直接覆盖前传的,连个预警都没有。真正能扛住这种场景的做法,是基于文件内容计算哈希,再配合目录分级存储。取md5_file()结果的前两位建子目录,后30位当文件名,既保证唯一性,又天然防覆盖,还能避免重复存多份冗余。关键前提:必须在临时文件被移动前调用md5_file(),并且提前把子目录创建好。

直接用 uniqid() 或时间戳拼接,根本挡不住并发上传同名文件——两个请求几乎同时进来,生成的文件名一模一样,后传的直接覆盖前传的。真正靠谱的做法是基于文件内容算哈希,再结合目录分级存储。
moveUploadFile() 的自动重命名ThinkPHP 默认的 moveUploadFile()(或新版的 validate()->move())确实会加随机后缀,但它只对「同一次请求内多个同名文件」起作用;跨请求、跨进程时,它不感知其他正在上传的文件,完全无法避免冲突。
md5_file() + 目录哈希分级生成唯一路径核心逻辑:读取临时文件,计算 md5_file() 得到 32 位哈希值,取前两位做子目录,后 30 位作文件名。这样既唯一、又天然防重、还利于海量文件分散存储。
$_FILES 临时文件未被移动前调用 md5_file(),否则读不到内容file_get_contents() 全读再 md5(),大文件会爆内存;md5_file() 是流式计算,安全$_FILES['file']['size'] 快速过滤空文件,省掉无效计算uploads/ab/abcdef01234567890123456789012345.jpguploadMaxSize 和临时文件生命周期如果文件超大,PHP 可能在你调用 md5_file() 前就清理了 tmp_name ——这不是 ThinkPHP 的锅,是 PHP 自身配置和 post_max_size / upload_max_filesize 限制导致的。
upload_max_filesize 和 post_max_size 设置合理,且大于预期最大上传体积move();最好在验证通过后立刻算哈希、生成目标路径,再一次性移动tmp_name 生命周期更短,必须严格检查 is_uploaded_file() 再操作哈希本身不难,难的是哈希时机卡在临时文件有效期内,以及目录结构得提前建好——漏掉 mkdir($subDir, 0755, true),写入直接失败,错误还藏在底层,不容易一眼看出来。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8