Laravel怎么处理大文件上传_Laravel如何分片上传视频【代码】

2次阅读

大文件上传失败主因是PHP底层限制而非laravel,需同步调整php.ini中upload_max_filesize、post_max_size、max_execution_time、max_input_time,并配置nginx的client_max_body_size;同时确保上传临时目录可写、磁盘空间充足;分片上传需前后端协作实现,用文件级hash(如sha256)支持秒传与断点续传,每片须单独校验md5防损坏。

Laravel怎么处理大文件上传_Laravel如何分片上传视频【代码】

大文件上传直接失败,php.ini 限制是第一道坎

不是 Laravel 框架的问题,而是 PHP 底层拦住了。上传超限会直接返回 413 Request Entity Too Large 或静默截断,连 Laravel 的入口都进不去。

必须同步调低三处阈值:

  • upload_max_filesize(单文件上限,如 200M
  • post_max_size(整个 POST 请求体上限,需 ≥ upload_max_filesize
  • max_execution_timemax_input_time(避免超时中断,尤其网络慢时)

改完记得重启 PHP-FPM 或 apache。Nginx 还要额外加 client_max_body_size 200M;,否则它会在 PHP 前就拒掉请求。

request()->file() 拿不到大文件?检查临时目录和权限

即使 php.ini 改了,PHP 仍可能因临时目录不可写而丢弃上传文件,此时 request()->file('video') 返回 NULL,且无明显报错。

验证方式很简单:

  • 打印 ini_get('upload_tmp_dir') 看路径
  • is_writable() 检查该目录是否可写
  • 确认磁盘空间足够(df -h

常见坑:docker 容器里挂载的临时目录没给 www-data 写权限;或者 SELinux 启用后阻止了写入。

分片上传不是 Laravel 自带能力,得自己搭前后端协作流程

Laravel 不提供分片上传内置支持,所谓「Laravel 分片上传」其实是你控制前端切片 + 后端拼接,框架只负责收、存、校验。

关键设计点:

  • 前端按固定大小(如 5MB)切片,每片带唯一 identifier(如文件 hash)、filenamechunkIndextotalChunks
  • 后端用 Storage::put() 把每片存到临时位置(如 chunks/{identifier}/{index}
  • 收到最后一片时,用 Storage::readStream() 逐个读片、fopen('php://output', 'w') 拼接,再 Storage::put() 写成完整文件

别用 file_put_contents 直接拼 —— 大文件易爆内存;也别在数据库里存所有分片路径再查 —— 高并发下容易漏片或重复提交。

分片续传和秒传依赖客户端 hash,Hash::make() 不适用

Hash::make() 是为密码设计的慢哈希,不能用于文件内容校验。秒传和断点续传必须用 md5_file() 或前端 Web API 的 FileReader + crypto.subtle.digest() 算出文件级 hash(如 md5sha256)。

后端收到 hash 后,先查 storage/app/finished/{hash} 是否已存在,存在就跳过上传直接返回成功。注意:md5 碰撞概率虽低,但视频类大文件建议至少用 sha256,尤其是多用户共用系统时。

真实项目里最容易被忽略的是:前端没做分片 hash 校验,导致某一片传坏却没发现,最后拼出来的是损坏视频 —— 必须让每片也带自己的 md5,后端收到后立即校验再落盘。

text=ZqhQzanResources