news 2026/3/31 3:37:53

PHP中如何实现500M视频大文件的分片上传方案?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHP中如何实现500M视频大文件的分片上传方案?

开发者日记:大文件管理系统毕业设计攻坚实录
日期:2023年11月25日
天气:阴有小雨

作为一名江苏高校的计算机专业大三学生,我的毕业设计选题是全浏览器兼容的大文件管理系统,需支持20GB文件传输、文件夹层级结构保留,并覆盖IE8及国产信创浏览器(龙芯/红莲花/奇安信)。经过三周技术攻关,现将关键实现方案与代码片段整理如下,供同领域同学参考。


一、技术架构设计

1. 跨浏览器兼容方案
浏览器类型前端方案后端适配
IE8WebUploader Flash引擎禁用HTML5拖拽,改用表单提交
Chrome/FirefoxHTML5 File API + WebUploader混合模式支持分片并发上传
信创浏览器动态检测降级为单文件上传关闭WebSocket长连接
2. 系统架构图
客户端(Vue3) → 分片上传 → PHP处理 → 阿里云OSS存储 ↓ MySQL记录元数据(文件哈希/分片状态/用户权限)

二、核心代码实现

1. 前端兼容性组件(Vue3)
// src/components/SmartUploader.vueimport{onMounted,ref}from'vue';importWebUploaderfrom'webuploader';import{detectBrowser}from'@/utils/browserDetect';exportdefault{setup(){constprogress=ref(0);constbrowserInfo=detectBrowser();onMounted(()=>{constconfig={swf:browserInfo.isIE8?'/static/Uploader.swf':null,// IE8必需Flashserver:'/api/upload',pick:'#filePicker',accept:{title:'All Files',extensions:'*',mimeTypes:'*'},chunked:true,chunkSize:5*1024*1024,// 5MB分片threads:browserInfo.isLoongBrowser?1:3,// 龙芯浏览器单线程formData:{browserType:browserInfo.type,timestamp:Date.now()}};// 国产浏览器特殊处理if(browserInfo.isRedLotus){config.dnd=false;// 禁用拖拽上传config.disableGlobalDnd=true;}constuploader=WebUploader.create(config);// 文件夹上传处理(非IE8)if(!browserInfo.isIE8&&WebUploader.Browser.HTML5){uploader.on('filesQueued',(files)=>{files.forEach(file=>{if(file.relativePath){// HTML5文件夹结构traverseFolder(file,uploader);}else{uploader.upload(file);}});});}// 进度监控uploader.on('uploadProgress',(file,percentage)=>{progress.value=Math.round(percentage*100);});});// 递归解析文件夹(HTML5 API)consttraverseFolder=(entry,uploader)=>{constdirReader=entry.createReader();dirReader.readEntries(entries=>{entries.forEach(subEntry=>{if(subEntry.isFile){subEntry.file(file=>{file.relativePath=`${entry.relativePath}/${file.name}`;uploader.addFiles(file);});}else{subEntry.relativePath=`${entry.relativePath}/${subEntry.name}`;traverseFolder(subEntry,uploader);}});});};return{progress};}};
2. 后端分片处理(PHP)
// api/upload_handler.php['accessKeyId'=>'your-aliyun-key','accessKeySecret'=>'your-aliyun-secret','endpoint'=>'oss-cn-shanghai.aliyuncs.com','bucket'=>'your-bucket'],'mysql'=>['host'=>'localhost','dbname'=>'file_manager','user'=>'root','pass'=>'password']];// 处理分片上传try{$pdo=newPDO("mysql:host={$config['mysql']['host']};dbname={$config['mysql']['dbname']}",$config['mysql']['user'],$config['mysql']['pass']);$chunkIndex=$_POST['chunk']??0;$totalChunks=$_POST['chunks']??1;$fileMd5=$_POST['md5']??md5_file($_FILES['file']['tmp_name']);// 兼容IE8$relativePath=$_POST['relativePath']??'';$userId=$_SESSION['user_id']??0;// 存储临时分片$chunkDir="/tmp/chunks/{$fileMd5}";if(!is_dir($chunkDir))mkdir($chunkDir,0777,true);move_uploaded_file($_FILES['file']['tmp_name'],"{$chunkDir}/{$chunkIndex}");// 记录分片状态$stmt=$pdo->prepare("REPLACE INTO file_chunks (md5, chunk_index, total_chunks, user_id, created_at) VALUES (?, ?, ?, ?, NOW())");$stmt->execute([$fileMd5,$chunkIndex,$totalChunks,$userId]);// 合并分片(最后一个分片)if($chunkIndex==$totalChunks-1){$ossPath="uploads/{$userId}/".ltrim($relativePath,'/');mergeChunks($fileMd5,$totalChunks,$ossPath,$config);// 记录完整文件信息$fileStmt=$pdo->prepare("INSERT INTO files (name, path, md5, size, user_id, created_at) VALUES (?, ?, ?, ?, ?, NOW())");$fileStmt->execute([basename($relativePath),$ossPath,$fileMd5,$_POST['size']??filesize($_FILES['file']['tmp_name']),$userId]);echojson_encode(['status'=>'completed','path'=>$ossPath]);}else{echojson_encode(['status'=>'pending']);}}catch(Exception$e){http_response_code(500);echojson_encode(['error'=>$e->getMessage()]);}// 分片合并函数functionmergeChunks($md5,$chunks,$ossPath,$config){$tempFile="/tmp/{$md5}_merged";$ossClient=newOssClient($config['oss']['accessKeyId'],$config['oss']['accessKeySecret'],$config['oss']['endpoint']);// 合并本地文件for($i=0;$i<$chunks;$i++){file_put_contents($tempFile,file_get_contents("/tmp/chunks/{$md5}/{$i}"),FILE_APPEND);}// 上传至OSS$ossClient->uploadFile($config['oss']['bucket'],$ossPath,$tempFile);// 清理临时文件unlink($tempFile);for($i=0;$i<$chunks;$i++){unlink("/tmp/chunks/{$md5}/{$i}");}rmdir("/tmp/chunks/{$md5}");}
3. 数据库表设计
-- 文件分片状态表CREATETABLE`file_chunks`(`id`BIGINTAUTO_INCREMENTPRIMARYKEY,`md5`VARCHAR(32)NOTNULLCOMMENT'文件唯一标识',`chunk_index`INTNOTNULLCOMMENT'分片序号',`total_chunks`INTNOTNULLCOMMENT'总分片数',`user_id`INTNOTNULLCOMMENT'关联用户',`created_at`DATETIMENOTNULLCOMMENT'记录时间',UNIQUEKEY`md5_chunk`(`md5`,`chunk_index`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;-- 文件元数据表CREATETABLE`files`(`id`BIGINTAUTO_INCREMENTPRIMARYKEY,`name`VARCHAR(512)NOTNULLCOMMENT'文件名(含扩展名)',`path`VARCHAR(1024)NOTNULLCOMMENT'OSS存储路径',`md5`VARCHAR(32)NOTNULLCOMMENT'文件哈希值',`size`BIGINTNOTNULLCOMMENT'文件大小(字节)',`user_id`INTNOTNULLCOMMENT'上传用户ID',`created_at`DATETIMENOTNULLCOMMENT'上传时间',INDEX`idx_user_md5`(`user_id`,`md5`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;

三、关键问题解决方案

  1. IE8文件夹上传

    • 方案:通过``的降级处理
    • 代码:
      // 兼容IE8的文件夹选择if(browserInfo.isIE8){document.getElementById('legacyFolderInput').onclick=()=>{document.getElementById('legacyInput').click();};document.getElementById('legacyInput').onchange=(e)=>{constfiles=e.target.files;// 模拟文件夹结构(需后端配合解析路径)};}
  2. 龙芯浏览器性能优化

    • 发现:龙芯CPU在多线程分片时CPU占用率达100%
    • 解决:强制单线程上传(threads: 1
  3. 20GB文件内存控制

    • 前端:使用FileReader.readAsArrayBuffer分块读取
    • 后端:PHP配置memory_limit = -1(由分片逻辑接管内存)

四、毕业设计创新点

  1. 智能降级机制

    • 通过User-Agent自动切换上传策略
    // 浏览器检测示例exportfunctiondetectBrowser(){constua=navigator.userAgent;return{isIE8:ua.includes('MSIE 8.0'),isLoongBrowser:ua.includes('LoongBrowser'),isRedLotus:ua.includes('RedLotus'),type:ua.includes('Edge')?'edge':ua.includes('Firefox')?'firefox':'unknown'};}
  2. 信创浏览器安全加固

    • 禁用WebUploader的Flash引擎(部分信创浏览器Flash存在漏洞)
    • 强制HTTPS传输分片数据
  3. 可视化上传监控

    • 基于ECharts实现实时速度/剩余时间预测

求助信息:目前奇安信浏览器在合并分片时出现路径截断问题,欢迎加入QQ群374992201共同调试!

今日进展:完成基础分片上传功能,明日将实现断点续传逻辑。


(签名)
江苏某高校 · 计算机1903班 · 李想
2023年11月25日 夜

项目资源

  • GitHub仓库(待开源):https://github.com/jsu-graduation/file-manager
  • 测试环境访问:http://test.yourdomain.com:8080/uploader
  • 文档中心:/docs/目录下的《全浏览器兼容方案.pdf》

致谢:感谢群内陈工提供的龙芯浏览器测试机,以及赵学长分享的阿里云OSS性能优化方案!

安装环境

PHP:7.2.14

调整块大小

NOSQL

NOSQL不需要任何配置,可以直接访问测试

SQL

创建数据库

您可以直接复制脚本进行创建

配置数据库连接

安装依赖

访问页面进行测试

数据表中的数据

效果预览

文件上传

文件刷新续传

支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传

文件夹上传

支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。

免费下载示例

点击下载完整示例

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/27 23:56:02

无锡黑锋 HF2304 同步升压DC变换器技术解析

在便携式电子设备蓬勃发展的今天&#xff0c;如何从有限的电池能量中榨取每一分电力&#xff0c;并转化为稳定、洁净的供电&#xff0c;是每一款产品面临的底层挑战。HF2304 正是为此类挑战而生的高效解决方案。它摒弃了传统升压电路复杂的周边配置与可观的静态损耗&#xff0c…

作者头像 李华
网站建设 2026/3/18 2:05:21

无锡黑锋 HF3121 PWM控制DC-DC升压控制器技术解析

在驱动OLED、电子纸等需要较高偏置电压的显示组件时&#xff0c;如何从低压锂电池中高效、稳定地生成一个可精确设定的高压电源&#xff0c;是移动设备设计中的关键环节。HF3121 正是为此类高压、小电流应用场景量身定制的专用解决方案。它摒弃了常见的集成开关管方案&#xff…

作者头像 李华
网站建设 2026/3/24 19:54:20

网安人必备!5 款漏洞挖掘扫描工具,高效搞定各类漏洞检测

网安人想挖漏洞赚钱&#xff0c;没有趁手的工具怎么行呢&#xff1f; 今天来为大家介绍5款进阶版漏洞挖掘扫描工具&#xff0c;掌握后保证挖到高危&#xff0c;真正实现财富自由&#xff01; 第一款&#xff1a;Trivy 一款开源漏洞扫描程序&#xff0c;使用很容易&#xff0…

作者头像 李华
网站建设 2026/3/17 21:37:51

【开题答辩全过程】以 基于SpringBoot的多多餐饮娱乐管理系统为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

作者头像 李华
网站建设 2026/3/18 0:13:03

【金融项目实战】9_接口测试 _BeautifulSoup基本使用

文章目录一、基本介绍二、使用步骤2.1 安装2.2 如何使用三、示例一、基本介绍 Beautiful Soup是一个可以从HTML或XMIL文计中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.Beautiful…

作者头像 李华
网站建设 2026/3/27 21:41:16

ops-transformer RoPE位置编码 复数旋转硬件加速实战

摘要 本文将深度解析cann项目中ops-transformer的RoPE位置编码实现&#xff0c;聚焦/operator/ops_transformer/rope/rotary_position_embedding.cpp的关键优化技术。核心内容包括sin/cos表预计算机制、向量指令融合策略&#xff0c;以及如何在NPU上实现复数旋转操作的高效硬件…

作者头像 李华