大文件分片上传在symfony中必须自主控制全流程,因php和nginx默认限制(如upload_max_filesize=2m、413错误、超时、内存溢出)无法支持;需前端切片、后端通过fileid/chunkindex/totalchunks校验调度,手动读取原始body存临时分片,redis记录已传索引,全量到位后流式合并。

大文件分片上传在 Symfony 中不能靠常规表单或 UploadedFile 直接处理——它本质是绕过 PHP 和 Web 服务器的底层限制,必须从前端切片、后端状态管理到合并逻辑全程自主控制。
为什么不能用默认上传方式
PHP 的 upload_max_filesize 和 post_max_size 默认仅 2M–8M;UploadedFile 会尝试将整个文件载入内存或临时磁盘,500MB 视频类文件极易触发:
- Nginx 返回 413 Request Entity Too Large
- PHP 超时(max_execution_time)或内存溢出(memory_limit)
- 请求中途断开,无重传机制
前后端协同的关键参数
分片不是“前端随便切、后端随便收”,服务端需依赖三个明确字段做校验和调度:
- fileId:全局唯一标识(如 UUID),用于隔离不同上传任务
- chunkIndex:当前分片序号(从 0 开始),决定写入顺序
- totalChunks:总分片数,用于判断是否收到最后一片
这些应通过 Query 参数传递(如 ?fileId=abc123&chunkIndex=5&totalChunks=20),避免 FormData 混淆 multipart 边界。
一款AI工具,主要用于将PREQSTATION编码任务委派给Claude Code、Codex CLI或Gemini CLI,采用PTY安全执行(工作目录+后台+监控),适合需要提升相关任务效率的用户。
后端安全接收与临时存储
不要调用 $request->files->get('file')——分片数据在原始 body 中,需手动读取:
- 用
$request->getContent()获取二进制分片内容 - 校验内容长度非空,防止空片写入
- 路径按
/tmp/uploads/{fileId}/{chunkIndex}组织,确保隔离性 - 用
Filesystem::mkdir()创建目录,避免权限问题 - 用
file_put_contents()写入,不经过move_uploaded_file()
完整性校验与合并时机
收到 chunkIndex == totalChunks - 1 并不等于可以立即合并——必须先确认所有分片已到位:
- 以
fileId为 Redis key 前缀,用SET fileId:abc123:chunks记录已上传的索引 - 合并前执行
SCARD检查集合大小是否等于totalChunks - 缺片则返回
400 Missing chunk,前端可据此触发重传 - 完整后按序打开各分片(
fopen(..., 'rb')),用fwrite()流式写入目标文件 - 合并完成再移入正式存储路径(如
public/uploads/xxx.mp4)
不复杂但容易忽略










