laravel大文件分片上传通过前端切片、服务端暂存与合并实现,支持断点续传和异步处理。前端按2mb切片并上传,服务端用redis记录状态,最后流式合并或交由队列异步完成,同时基于sha-256校验去重。

如果您在Laravel应用中需要上传大文件,但受限于PHP内存限制、超时设置或网络不稳定导致单次上传失败,则可采用分片上传策略。以下是实现多文件分片上传的具体方法:
一、前端分片与合并逻辑
该方法依赖前端将大文件切分为固定大小的块(如2MB/片),逐个上传,并在服务端记录分片状态,最终触发合并操作。需配合唯一文件标识(如文件hash)避免重复上传相同分片。
1、使用JavaScript FileReader API读取文件并按指定大小切片。
2、为每个分片生成唯一标识符,包含文件名、总片数、当前序号和文件MD5。
3、通过POST请求向Laravel接口上传单个分片,携带分片元数据(如chunkIndex、totalChunks、fileIdentifier)。
4、前端在所有分片上传成功后,发起合并请求,传入fileIdentifier及原始文件名。
二、Laravel服务端分片接收与存储
此方法在控制器中接收分片,校验完整性后暂存至临时目录,使用Redis或数据库记录已上传分片索引,防止重复提交或丢失。
1、定义路由 POST /api/upload/chunk 接收单个分片,验证请求中是否包含fileIdentifier、chunkIndex、totalChunks参数。
2、检查storage/app/chunks/{fileIdentifier}/目录是否存在,若不存在则创建。
3、将接收到的文件内容写入storage/app/chunks/{fileIdentifier}/{chunkIndex},使用file_put_contents确保原子写入。
4、使用Redis SETNX命令记录该分片已接收,键名为upload:chunks:{fileIdentifier}:{chunkIndex},值为1,过期时间设为24小时。
三、服务端分片合并与文件落盘
当所有分片确认上传完成,系统将按序号拼接各分片内容,生成完整文件,并删除临时分片目录。合并前需校验分片总数与实际接收数量一致。
1、定义路由 POST /api/upload/merge 接收fileIdentifier和originalName参数。
部分功能简介:商品收藏夹功能热门商品最新商品分级价格功能自选风格打印结算页面内部短信箱商品评论增加上一商品,下一商品功能增强商家提示功能友情链接用户在线统计用户来访统计用户来访信息用户积分功能广告设置用户组分类邮件系统后台实现更新用户数据系统图片设置模板管理CSS风格管理申诉内容过滤功能用户注册过滤特征字符IP库管理及来访限制及管理压缩,恢复,备份数据库功能上传文件管理商品类别管理商品添加/修改/
2、从Redis中查询upload:chunks:{fileIdentifier}:*匹配的所有key,统计实际接收分片数。
3、若统计数量等于totalChunks,则按chunkIndex升序读取各分片内容,使用fopen('php://output', 'wb')流式写入目标路径storage/app/uploads/{originalName}。
4、合并完成后,执行Redis DEL upload:chunks:{fileIdentifier}:* 并递归删除storage/app/chunks/{fileIdentifier}/目录。
四、基于Laravel Job的异步合并处理
为避免HTTP请求超时,可将合并操作交由队列异步执行。上传完最后一个分片后仅触发Job投递,由Worker进程完成读取、拼接与清理。
1、在分片上传完成判断逻辑中,调用dispatch(new MergeChunkJob($fileIdentifier, $originalName))。
2、MergeChunkJob构造函数中保存$fileIdentifier和$originalName,并在handle()方法中执行分片读取与合并。
3、使用Storage::disk('local')->readStream()逐个打开分片流,通过stream_copy_to_stream()追加写入目标文件句柄。
4、合并成功后,调用Storage::disk('local')->deleteDirectory("chunks/{$fileIdentifier}")清除临时数据。
五、断点续传与分片去重支持
该方法通过文件内容哈希(如SHA-256)识别已存在分片,允许客户端跳过已上传成功的块,提升大文件重试效率。
1、前端在上传前计算每个分片的SHA-256值,并随请求发送sha256参数。
2、服务端接收分片前,先查询Redis中是否存在键upload:sha256:{sha256},若存在则直接返回“已存在”,不重复写入。
3、若不存在,则正常写入分片,并同时设置upload:sha256:{sha256} = {fileIdentifier}:{chunkIndex},TTL同上。
4、在合并阶段,依据fileIdentifier查出全部chunkIndex列表,再反查对应sha256是否全部命中,缺失任一分片则拒绝合并并返回错误码400。









