当前位置: 首页 > news >正文

国产化环境中PHP如何上传500M以上的超大附件?

开发者日记 - 大文件传输系统开发实录
日期:2023年11月15日
天气:阴

项目背景与需求梳理

作为江苏的一名独立开发者,近期承接了一个企业级文件传输系统项目,核心需求如下:

  1. 大文件支持:单文件20GB,需兼容文件夹上传(保留层级结构)。
  2. 断点续传:跨会话、跨设备(重启电脑后仍可恢复)。
  3. 全平台兼容:Windows/macOS/Linux,浏览器覆盖IE8到Chrome/Firefox/Safari等。
  4. 技术栈
    • 前端:Vue3 + WebUploader(或H5 API)
    • 后端:PHP + MySQL(记录分片信息)
    • 存储:华为云OBS(对象存储)
  5. 特殊要求:免费开源代码、7×24小时技术支持(通过QQ群374992201)。

技术选型与挑战

1. 上传组件选择
  • WebUploader:兼容IE8+,支持分片、断点续传,但需手动封装文件夹解析逻辑。
  • H5 File API:现代浏览器支持良好,但IE8/9需Polyfill,且文件夹上传需依赖webkitdirectory(非标准)。
    决策:以WebUploader为主,H5作为降级方案,通过User-Agent判断浏览器类型动态切换。
2. 断点续传设计
  • 分片存储:将大文件切分为5MB分片,上传时记录已完成的分片序号。
  • 进度持久化
    • 前端:使用localStorageIndexedDB存储临时进度(跨会话)。
    • 后端:MySQL表记录文件唯一标识(MD5)、总分片数、已上传分片列表。
  • 跨设备恢复:通过文件MD5校验匹配历史记录,从华为云OBS合并已上传分片。
3. 文件夹上传实现
  • WebUploader扩展:监听directory事件,递归解析文件夹结构,生成扁平化的文件路径列表(如/parent/child/file.txt)。
  • 后端处理:接收路径信息,在华为云OBS中按原路径创建空文件夹(通过putObject设置Content-Type: application/directory)。

核心代码实现

前端(Vue3 + WebUploader)
// src/components/Uploader.vueimportWebUploaderfrom'webuploader';import'webuploader/dist/webuploader.css';exportdefault{mounted(){constuploader=WebUploader.create({swf:'/path/to/webuploader.swf',// IE8/9兼容server:'/api/upload',chunked:true,chunkSize:5*1024*1024,// 5MB分片formData:{fileMd5:'',// 通过后端接口预先计算isDir:false// 标记是否为文件夹},files:[]// 存储文件夹结构});// 监听文件夹选择(仅现代浏览器)document.getElementById('filePicker').addEventListener('change',(e)=>{constfiles=e.target.files;if(files.length&&files[0].webkitRelativePath){// 递归解析文件夹constparseDir=(file,path='')=>{constfullPath=path+file.name;if(file.isDirectory){// 模拟文件夹上传(实际需后端支持)return;}uploader.addFiles({name:file.name,relativePath:fullPath,size:file.size,type:file.type});};Array.from(files).forEach(file=>parseDir(file));}});// 断点续传:从localStorage加载进度constresumeData=localStorage.getItem('upload_progress');if(resumeData){const{fileMd5,chunks}=JSON.parse(resumeData);uploader.option('formData',{fileMd5,isDir:false});// 跳过已上传的分片(需后端配合校验)}// 上传完成合并分片uploader.on('uploadSuccess',(file,response)=>{if(response.needMerge){fetch('/api/merge',{method:'POST',body:JSON.stringify({fileMd5:response.fileMd5})});}});}};
后端(PHP + MySQL)
// api/upload.phpprepare("INSERT INTO upload_chunks (file_md5, chunk_index, uploaded_at) VALUES (?, ?, NOW()) ON DUPLICATE KEY UPDATE updated_at = NOW()");$stmt->execute([$fileMd5,$chunkIndex]);// 上传分片到华为云OBS$obsClient=new\OBS\ObsClient(['key'=>'your-access-key','secret'=>'your-secret-key','endpoint'=>'obs.cn-east-3.myhuaweicloud.com']);$obsPath="uploads/{$fileMd5}/chunk_{$chunkIndex}";$obsClient->putObject(['Bucket'=>'your-bucket','Key'=>$obsPath,'SourceFile'=>$_FILES['file']['tmp_name']]);// 检查是否所有分片已上传$chunksCount=$pdo->query("SELECT COUNT(*) FROM upload_chunks WHERE file_md5 = '{$fileMd5}'")->fetchColumn();$totalChunks=$_POST['totalChunks'];// 前端传递总分片数if($chunksCount===$totalChunks){echojson_encode(['needMerge'=>true,'fileMd5'=>$fileMd5]);}else{echojson_encode(['success'=>true]);}?>
MySQL表结构
CREATETABLEupload_chunks(idINTAUTO_INCREMENTPRIMARYKEY,file_md5VARCHAR(32)NOTNULL,chunk_indexINTNOTNULL,uploaded_atDATETIMEDEFAULTCURRENT_TIMESTAMP,UNIQUEKEY(file_md5,chunk_index));

测试与优化

  1. 兼容性测试
    • IE8:需引入es5-shimjson2.js
    • 文件夹上传:在Chrome中测试webkitRelativePath,IE使用ActiveX模拟(需用户授权)。
  2. 性能优化
    • 分片并发上传(WebUploader默认支持3个并发)。
    • 华为云OBS启用CDN加速下载。
  3. 断点续传验证
    • 手动终止进程后,重启上传时跳过已完成的分片。

后续计划

  1. 完善QQ群技术支持文档,提供常见问题解答(FAQ)。
  2. 开源代码至GitHub,附详细部署说明。
  3. 考虑增加WebSocket实时进度通知功能。

今日总结:核心功能已跑通,但IE兼容性和文件夹解析仍需打磨。欢迎大神加入QQ群交流优化方案!


(日记结束)

:实际项目中需补充安全校验(如文件类型白名单、分片签名防篡改),代码仅为示例框架,需根据业务需求调整。

安装环境

PHP:7.2.14

调整块大小

NOSQL

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

SQL

创建数据库

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

配置数据库连接

安装依赖

访问页面进行测试

数据表中的数据

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

免费下载示例

点击下载完整示例

http://www.jsqmd.com/news/357741/

相关文章:

  • 2026年比较好的安徽纪念章售货机/安徽激光雕刻售货机销售厂家 - 行业平台推荐
  • GitHub开源协作:参与RMBG-2.0项目贡献指南
  • Qwen3-4B开源镜像免配置部署:torch_dtype=‘auto‘精度自适应教程
  • 2026年质量好的气膜匹克球馆/气膜儿童乐园哪家便宜源头直供参考(真实参考) - 行业平台推荐
  • ChatGLM-6B实战案例:用Python调用API实现自动化报告生成流程
  • AI普惠化趋势:YOLOv8让中小企业也能用上工业级检测
  • Ollma部署LFM2.5-1.2B-Thinking:开源可部署+低延迟+高鲁棒性三重保障
  • 构建私有文档大脑:MinerU + 向量数据库实战
  • 2026年比较好的气膜煤棚/工业气膜工厂采购指南如何选(实用) - 行业平台推荐
  • Gemma-3-270m在VMware虚拟机中的部署优化
  • php python+vue网上书店需求
  • SeqGPT-560M零样本文本理解入门:什么是In-Context Learning?中文Prompt怎么写?
  • GTE中文嵌入模型详细步骤:自定义batch_size提升GPU吞吐量
  • EasyAnimateV5-7b-zh-InP与Xshell结合:远程服务器部署指南
  • CentOS安装配置AWStats,网站流量日志分析指南
  • 云容笔谈企业级部署:支持API调用的东方美学AI服务容器化实践
  • Qwen2.5-7B-Instruct生成代码质量评估:从原理到实践
  • 美胸-年美-造相Z-Turbo镜像结构解析:/root/workspace/xinference.log日志机制
  • Visio流程图设计:EasyAnimateV5-7b-zh-InP视频生成流程可视化
  • php python+vue网上人才招聘管理系统_开题报告
  • ollama部署embeddinggemma-300m:轻量嵌入模型在边缘AI网关中的部署方案
  • Python爬虫辅助CTC语音唤醒数据收集
  • SeqGPT-560M Web界面源码解读:前端Vue组件结构+后端FastAPI接口设计逻辑
  • SenseVoice Small效果展示:英语学术报告语音转写参考文献自动提取
  • DeepSeek-OCR开源镜像实战:对接企业微信/钉钉,实现移动端拍照直解析
  • FaceRecon-3D基础教程:理解UV纹理图原理与3D人脸重建数学本质
  • Qwen3-VL-8B-Instruct-GGUF在Matlab中的使用:科学计算增强
  • LoRA训练助手企业落地:电商直播团队快速生成商品图LoRA训练数据
  • Qwen3-VL-8B企业级应用:集成至OA系统实现‘文档上传→自动摘要→问答交互’闭环
  • GPEN案例深度解析:一张毕业合照中百人面部同步增强