php实现文件断点续传需前后端协同:前端分片上传并查询进度,服务端用redis存状态、校验分片、按序合并并验证完整性,同时做好并发控制与安全防护。

PHP 实现文件断点续传,核心在于客户端(如浏览器或 App)与服务端协同记录上传进度,通过分块上传 + 校验 + 进度恢复机制完成。关键不是“PHP 单独做”,而是配合前端(如使用 XMLHttpRequest 或 fetch 的分片上传)和服务端逻辑共同实现。
1. 前端需支持分片上传与断点识别
客户端必须将大文件切分成多个小块(例如每块 1MB),并为每个块携带唯一标识:文件唯一 ID(如 MD5 文件名)、当前分片序号、总分片数、分片大小等。上传中断后,前端可先向服务端发起查询请求(如 /upload/status?file_id=xxx),获取已成功上传的分片列表,再跳过已传部分,继续上传剩余分片。
- 推荐用
Blob.slice()切片,配合FormData逐块提交 - 每个分片请求附带
headers如X-File-Id、X-Chunk-Index、X-Total-Chunks - 上传失败时,不重试整文件,只重传当前失败分片
2. 服务端需持久化上传状态
PHP 接收分片时,不能直接合并写入最终文件(否则无法恢复)。应先将每个分片保存为临时文件(如 /uploads/chunks/{file_id}_{index}.part),同时用轻量存储记录已接收的分片索引(可用 Redis、SQLite 或 JSON 文件)。
- 示例状态记录结构:
{"file_id": "abc123", "uploaded_chunks": [0,1,3,4], "total": 10, "size": 10485760} - 建议用 Redis 存储状态:键为
upload:abc123,值为 JSON 字符串,支持原子操作和过期自动清理 - 接收分片时校验
Content-Range或自定义分片序号,防止乱序/重复提交
3. 合并分片与完整性校验
当所有分片上传完成(即 uploaded_chunks 数量等于 total),触发合并逻辑。PHP 按序读取各 .part 文件,追加写入目标文件。合并后务必校验最终文件完整性——常用方式是比对客户端传来的文件总 MD5 或 SHA256 与服务端计算结果是否一致。
- 合并时用
fopen(..., 'ab')追加模式,避免内存溢出 - 校验失败则删除目标文件和所有分片,返回错误提示,前端可重新上传
- 合并成功后清理分片文件和 Redis 状态,防止磁盘占用累积
4. 注意并发与安全性细节
多用户同时上传同名文件、恶意伪造分片序号、超时未完成上传等情况必须处理。PHP 脚本需有超时控制(如设置 max_execution_time = 0 仅限上传脚本),但更推荐用队列或异步任务处理合并操作。
- 每个
file_id加分布式锁(Redis SETNX)避免并发合并冲突 - 验证
file_id是否合法(如 base64 编码+签名),防止路径遍历或越权访问 - 临时分片目录需设在 Web 不可访问路径,并定期清理超时(如 24 小时)未完成的上传任务
不复杂但容易忽略。断点续传本质是“状态可存、过程可逆、结果可验”,PHP 做好分片接收、状态管理、安全合并三件事,配合前端协作即可稳定落地。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











