发布于2026-07-17 阅读(0)
扫一扫,手机访问
Lara vel大文件分块上传需从前端分片、服务端原子写入、流式合并、Redis断点续传及自动化清理五方面实现:前端用File.slice()切片并携带SHA-256标识与序号;服务端直读HTTP body流并加锁写入临时目录;合并时调用cat命令流式拼接;Redis记录已传分片支持续传;上传后自动清理临时文件并配置Nginx client_max_body_size。

在Lara vel中上传大文件(比如视频、备份包),如果直接硬上,很可能遭遇超时、内存溢出或者413错误。核心原因在于PHP和Web服务器对单次请求体积有限制,只要没启用分块机制,文件越大越容易翻车。下面这套方案,从存储层出发,围绕安全、高效、可扩展三个目标,把分块上传的完整实现拆开来讲。
这一步是地基。只有让服务端准确识别每个分片属于哪个文件、排在第几块,后续才能有序重组,同时为断点续传铺路。关键是把文件哈希当作唯一标识,而不是依赖文件名或时间戳——两个同名文件不会互相覆盖。
具体做法:前端用File.slice()按固定大小(比如5MB)把原始文件切成有序数组。接着计算整个文件的SHA-256哈希值,作为fileIdentifier。每个分片请求要带上四个必须字段:identifier(哈希值)、chunkNumber(从0开始递增)、totalChunks(总片数)、filename(原始文件名,用于最终落盘)。发送时用fetch传二进制流,Content-Type设为application/octet-stream,别用FormData——multipart解析额外消耗性能。
这是最容易踩坑的一环。千万别用Lara vel默认的$request->file(),它会触发PHP完整解析multipart数据,大文件直接内存溢出。正确的做法是直接读取原始HTTP body流,完全绕过PHP的内存加载。
定义路由POST /api/upload/chunk,在控制器里先校验identifier、chunkNumber、totalChunks是否合法。接着调用$request->getContent()获取原始二进制流——注意,这里不能用$request->file('file')。然后构造临时存储路径:storage_path("app/chunks/{$identifier}/{$chunkNumber}"),用mkdir(..., 0755, true)确保父目录存在。写入时加独占锁:file_put_contents($filePath, $content, LOCK_EX),防止并发写入同一个分片把数据搞乱。
文件分片全传完后,合并操作要交给操作系统内核完成,PHP只负责发命令,不参与内存加载。否则遇到GB级文件,Storage::put()分分钟卡死进程。
客户端发起POST /api/upload/merge?identifier=xxx请求后,先检查Redis里uploaded_chunks:{$identifier}的计数值是否等于totalChunks。然后遍历storage/app/chunks/{$identifier}/目录下所有分片文件,按chunkNumber升序排序,确认每个文件大小大于0。接着拼接一条shell命令:
cat storage/app/chunks/{$identifier}/* > storage/app/uploads/{$finalName}
通过exec()或Lara vel的Process组件执行。执行前务必确认web用户(比如www-data)对chunks/和uploads/目录有读写权限,而且磁盘剩余空间要大于目标文件大小。
大文件上传最怕中途中断得从头再来。用Redis记录每个分片的上传状态,客户端可以随时查询哪些分片已成功,直接跳过重传。
每个分片写入成功后,马上执行Redis::sAdd("uploaded_chunks:{$identifier}", $chunkNumber)。提供一个GET /api/upload/chunks/{identifier}接口,返回已经上传的分片索引数组(比如[0,1,2,4]),直接从Redis里取,不走磁盘,响应迅速。合并完成后,记得执行Redis::del("uploaded_chunks:{$identifier}")清理状态。为了防止Redis里残留脏数据,所有状态键必须设置过期时间,比如SETEX uploaded_chunks:abc 86400 [0,1,2]。
临时分片如果不清除,日积月累会把磁盘塞爆。合并成功后,递归删除storage/app/chunks/{$identifier}/目录,用Filesystem::deleteDirectory()而不要用shell的rm -rf。再注册一个artisan命令php artisan upload:cleanup,让它定时扫描chunks/目录下超过24小时还没被合并的目录,直接清理掉。
部署时别忘了设置目录权限:chmod -R 755 storage/app/chunks storage/app/uploads,然后chown -R www-data:www-data storage/app/chunks storage/app/uploads。最后,Nginx的client_max_body_size必须配置成至少128m,否则分片请求还没到PHP就被拦截,直接返回413错误。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8