Laravel如何实现多文件分片上传?(大文件处理)

5次阅读

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

Laravel如何实现多文件分片上传?(大文件处理)

如果您在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参数。

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

text=ZqhQzanResources