php 8.5 防止文件重复上传需基于内容哈希校验与服务端状态控制:前端传文件完整哈希,服务端查缓存/数据库判断存在性;数据库加唯一索引兜底;上传会话绑定uuid并设ttl;前端禁用按钮、支持请求取消、接口幂等化。

PHP 8.5 中防止文件重复上传,核心不是靠“名字相同就拒绝”,而是建立可验证的**内容唯一性标识 + 服务端状态控制**。单纯比对文件名或扩展名极易被绕过,必须从文件本体出发做校验。
基于文件哈希的内容去重
上传前计算文件完整哈希(如 md5 或 sha256),服务端查库或缓存确认是否已存在相同哈希值:
- 前端分片上传时,先传 fileHash(整个文件的 md5)和 totalChunks,服务端用该 hash 查询临时表或 Redis 键 upload:{fileHash}
- 若记录存在且 status = 'completed',直接返回“文件已存在”,跳过上传流程
- 若存在但 status = 'uploading',可返回已传分片列表,支持断点续传;若不存在,则初始化上传会话并写入记录
- 注意:大文件用
hash_file('md5', $tmp_name)会阻塞,生产环境建议前端计算哈希后传入,服务端只做校验
数据库层唯一约束兜底
在存储文件元数据的表中,为文件哈希字段添加唯一索引,配合插入逻辑防并发漏检:
- 建表语句示例:
ALTER TABLE uploads ADD UNIQUE INDEX idx_file_hash (file_hash); - 插入时使用
INSERT IGNORE或ON DUPLICATE KEY UPDATE,避免因竞态导致重复入库 - 即使哈希校验环节短暂失效(如缓存未及时更新),数据库索引也能拦截最终写入
上传会话生命周期管理
每个上传任务绑定一个临时会话 ID(如 UUIDv4),关联 fileHash 和超时时间,防止无效残留:
- 会话创建时写入 Redis:
SETEX upload_session:{sessionId} 1800 '{json}'(TTL 30 分钟) - 每完成一个分片,更新会话中的 uploaded_chunks 计数;合并完成后删掉该 key
- 定时任务或中间件定期扫描过期会话,清理对应临时文件和数据库草稿记录
客户端配合:禁用+提示+幂等请求
后端再严密,也需前端协同减少误触发:
- 提交按钮点击后立即
disabled=true,并显示“上传中…”文字 - 使用 fetch 或 axios 时配置
signal支持取消重复请求,避免用户连点发多个上传请求 - 关键操作接口设计为幂等:同一 fileHash 的多次上传请求,返回相同 success 响应,不报错也不重复处理
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











