thinkphp原生upload类不支持视频断点续传,需采用前端切片+后端状态管理+分片合并模式:前端用file.slice切片、计算md5作为filehash、上传时携带分片信息;后端建upload_status表记录上传状态,提供/init、/chunk、/complete三接口实现校验、分片接收与合并。

ThinkPHP 原生的 Upload 类不支持视频断点续传,它只适用于小文件(几 MB 到几十 MB)的一次性上传。要让视频上传支持断点续传,必须放弃表单直传方式,改用「前端切片 + 后端状态管理 + 分片合并」的协作模式。
前端需做三件事
用 JavaScript 控制整个流程,不能依赖 <form></form> 提交:
- 用
File.slice()将视频按固定大小(如 5MB)切片,避免单请求过大 - 计算整个视频的 MD5(推荐
spark-md5库),作为该文件唯一指纹(fileHash) - 每个分片上传时,携带
fileHash、chunkIndex(从 0 开始)、totalChunks、fileName等参数
后端需建状态表并存分片
在数据库中新建一张 upload_status 表,至少包含以下字段:
-
file_hash:主键或唯一索引,对应前端传来的 MD5 -
uploading_count:已成功上传的分片数量 -
total_chunks:总分片数(首次上传时写入) -
status:值为uploading/completed/failed -
updated_time:最后更新时间,用于超时清理
每次收到一个分片,就更新该 file_hash 对应的 uploading_count,用 INSERT ... ON DUPLICATE KEY UPDATE 保证原子性。
分片接收与合并逻辑
控制器里提供三个接口:
-
/upload/init:校验
fileHash是否存在;若不存在,插入新记录,并返回totalChunks和确认可继续上传 -
/upload/chunk:接收当前分片二进制数据,保存为临时文件(如
uploads/chunks/{fileHash}/part_{index}),同时更新状态表 -
/upload/complete:检查
uploading_count === totalChunks,若满足,按序读取所有part_*文件,用fopen(..., 'wb')+fwrite合并成完整视频;合并成功后标记状态为completed,并删除所有临时分片
额外建议提升稳定性
不是必须但强烈推荐:
- 合并前加文件锁(
flock),防止并发完成请求导致重复写入 - 对临时分片目录设置定时清理任务(如超过 24 小时未完成的
file_hash记录及对应文件全部清除) - 前端上传前先调一次
/upload/check?fileHash=xxx,查出已传哪些分片,跳过重传 - 视频文件名不要直接用用户原始名,合并后生成带时间戳和 UUID 的安全路径,再存业务表关联
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











