news 2026/5/1 8:25:37

网页中使用PHP处理500M大附件上传有哪些方案?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
网页中使用PHP处理500M大附件上传有哪些方案?

开发者日记:2023年X月X日 星期X 武汉 阴

项目背景
今日正式启动客户的大文件传输系统项目,需求明确:支持20G文件/文件夹上传下载、跨平台(Windows/macOS/Linux)、全浏览器兼容(含IE8)、断点续传、保留文件夹层级结构。后端使用PHP + MySQL,存储用阿里云OSS,前端为Vue3 CLI + WebUploader/H5。客户强调高频文件夹上传场景,需极致优化用户体验。免费开源代码和7*24支持的压力依旧,但技术栈熟悉度较高,信心渐增。


技术选型与调整

  1. 前端框架

    • Vue3 CLI:组件化开发,配合@babel/polyfill兼容IE8。
    • WebUploader:核心上传组件,深度定制文件夹解析逻辑。
    • H5 File API:现代浏览器备用方案,IE8回退到Flash上传。
  2. 后端架构

    • PHP 8.1:处理分片上传、MySQL元数据存储、OSS直传。
    • MySQL 8.0:存储文件路径、分片状态、用户ID(InnoDB引擎保证事务)。
  3. 核心难点

    • 高频文件夹上传:优化递归解析性能,避免前端卡顿。
    • 断点续传稳定性:MySQL事务保证分片记录一致性。
    • IE8兼容性:Flash上传需处理跨域问题(crossdomain.xml)。

前端代码实现(Vue3 + WebUploader)

1. 文件夹上传组件
// src/components/FolderUploader.vueimport{ref,onMounted}from'vue';importWebUploaderfrom'webuploader';import'webuploader/dist/webuploader.css';exportdefault{setup(){constuploader=ref(null);constfolderTree=ref([]);onMounted(()=>{// 动态加载Flash(IE8兼容)if(!WebUploader.Uploader.support('HTML5')){WebUploader.Uploader.register({name:'flash',fn:()=>'/assets/Uploader.swf'});}uploader.value=newWebUploader.Uploader({swf:'/assets/Uploader.swf',server:'/api/upload.php',chunked:true,chunkSize:4*1024*1024,// 4MB分片formData:{fileId:'',relativePath:''// 关键:记录文件相对路径}});});consttriggerFolderInput=()=>{document.getElementById('folderInput').click();};// 递归解析文件夹(兼容现代浏览器)consthandleFolderSelect=(e)=>{constitems=e.target.files;if(items){consttree=[];for(leti=0;i<items.length;i++){constfile=items[i];constpath=file.webkitRelativePath||file.name;// 相对路径constsegments=path.split('/');// 构建树形结构letcurrentLevel=tree;segments.slice(0,-1).forEach(segment=>{letdir=currentLevel.find(item=>item.name===segment);if(!dir){dir={name:segment,type:'directory',children:[]};currentLevel.push(dir);}currentLevel=dir.children;});// 添加文件节点currentLevel.push({name:segments.pop(),type:'file',file:file,relativePath:path});}folderTree.value=tree;uploadFolder(tree);}};// 上传文件夹内容constuploadFolder=(tree)=>{tree.forEach(node=>{if(node.type==='directory'){uploadFolder(node.children);// 递归上传子目录}else{constformData=uploader.value.option('formData');formData.relativePath=node.relativePath;uploader.value.addFile(node.file,node.relativePath);}});uploader.value.upload();// 触发上传};return{triggerFolderInput,folderTree};}};
2. IE8兼容性处理

后端代码实现(PHP + MySQL)

1. 分片上传接口
setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);$stmt=$pdo->prepare(" INSERT INTO upload_progress (file_id, chunk_index, total_chunks, uploaded_at) VALUES (?, ?, ?, NOW()) ON DUPLICATE KEY UPDATE updated_at = NOW() ");$stmt->execute([$fileId,$chunkIndex,$totalChunks]);// 如果是最后一块,合并并上传OSSif($chunkIndex===$totalChunks-1){$finalPath="{$tempDir}/final_file";$fp=fopen($finalPath,'wb');for($i=0;$i<$totalChunks;$i++){$chunk=file_get_contents("{$tempDir}/chunk_{$i}");fwrite($fp,$chunk);}fclose($fp);// 上传OSS(需引入阿里云OSS SDK)require_once'oss-sdk/autoload.php';$ossClient=newOSS\OssClient($OSS_KEY,$OSS_SECRET,$OSS_ENDPOINT);$ossClient->putObject($OSS_BUCKET,"uploads/{$fileId}",$finalPath);// 清理临时文件array_map('unlink',glob("{$tempDir}/*"));rmdir($tempDir);// 保存文件元数据到MySQL$metaStmt=$pdo->prepare(" INSERT INTO file_metadata (file_id, relative_path, size, uploaded_at) VALUES (?, ?, ?, NOW()) ");$metaStmt->execute([$fileId,$relativePath,filesize($finalPath)]);}echojson_encode(['success'=>true,'fileId'=>$fileId]);}catch(Exception$e){http_response_code(500);echojson_encode(['error'=>$e->getMessage()]);}?>
2. MySQL表结构
-- 文件分片进度表CREATETABLE`upload_progress`(`id`int(11)NOTNULLAUTO_INCREMENT,`file_id`varchar(64)NOTNULLCOMMENT'文件唯一ID',`chunk_index`int(11)NOTNULLCOMMENT'分片索引',`total_chunks`int(11)NOTNULLCOMMENT'总分片数',`uploaded_at`datetimeNOTNULLDEFAULTCURRENT_TIMESTAMP,`updated_at`datetimeNOTNULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP,PRIMARYKEY(`id`),UNIQUEKEY`idx_file_chunk`(`file_id`,`chunk_index`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;-- 文件元数据表CREATETABLE`file_metadata`(`id`int(11)NOTNULLAUTO_INCREMENT,`file_id`varchar(64)NOTNULLCOMMENT'文件唯一ID',`relative_path`varchar(512)NOTNULLCOMMENT'文件相对路径',`size`bigint(20)NOTNULLCOMMENT'文件大小(字节)',`uploaded_at`datetimeNOTNULLDEFAULTCURRENT_TIMESTAMP,PRIMARYKEY(`id`),UNIQUEKEY`idx_file_path`(`file_id`,`relative_path`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;

断点续传实现

1. 前端恢复逻辑
// 检查未完成上传constcheckResume=async(fileId)=>{constres=awaitfetch(`/api/progress.php?fileId=${fileId}`);constdata=awaitres.json();if(data.completedChunks<data.totalChunks){uploader.value.option('formData',{fileId,chunk:data.completedChunks});uploader.value.upload();}};// 本地存储fileId(即使浏览器关闭)window.addEventListener('beforeunload',()=>{if(uploader.value.getFiles().length>0){localStorage.setItem('lastUploadId',uploader.value.option('formData').fileId);}});
2. 后端进度查询
'fileId is required']);exit;}try{$pdo=newPDO("mysql:host={$DB_HOST};dbname={$DB_NAME}",$DB_USER,$DB_PASS);$stmt=$pdo->prepare(" SELECT COUNT(*) AS completed, MAX(total_chunks) AS total FROM upload_progress WHERE file_id = ? ");$stmt->execute([$fileId]);$result=$stmt->fetch(PDO::FETCH_ASSOC);echojson_encode(['completedChunks'=>(int)$result['completed'],'totalChunks'=>(int)$result['total']]);}catch(Exception$e){http_response_code(500);echojson_encode(['error'=>$e->getMessage()]);}?>

今日总结

  • 进展:完成文件夹层级解析和PHP分片上传逻辑,IE8兼容性方案验证通过。
  • 问题
    1. WebUploader在IE8下对大文件夹性能较差,需优化DOM操作。
    2. MySQL事务需加强,避免分片记录残留。
  • 明日计划
    1. 实现OSS分片上传(避免本地合并临时文件)。
    2. 编写完整的开发文档和API接口说明。

求助:若有熟悉PHP文件处理或MySQL优化的高手,欢迎加入QQ群374992201指导!代码将完全开源回馈社区。


(注:实际项目需补充安全校验、OSS直传和性能监控代码。)

安装环境

PHP:7.2.14

调整块大小

NOSQL

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

SQL

创建数据库

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

配置数据库连接

安装依赖

访问页面进行测试

数据表中的数据

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

批量下载

支持文件批量下载

下载续传

文件下载支持离线保存进度信息,刷新页面,关闭页面,重启系统均不会丢失进度信息。

文件夹下载

支持下载文件夹,并保留层级结构,不打包,不占用服务器资源。

免费下载示例

点击下载完整示例

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

交易所源码开发:单语言VS多语言,到底该怎么选?

在区块链交易所源码开发领域&#xff0c;“技术选型”是所有开发者和项目方绕不开的第一道坎&#xff0c;而其中最具争议性的问题之一就是&#xff1a;交易所源码开发&#xff0c;到底用单语言好&#xff0c;还是多语言混合开发好&#xff1f;其实这个问题没有绝对的“标准答案…

作者头像 李华
网站建设 2026/4/28 11:55:57

论文写不动?最强的AI论文写作软件 —— 千笔·专业学术智能体

你是否也曾为论文的选题发愁&#xff1f;是否在深夜里对着空白文档无从下笔&#xff1f;又或者反复修改却总感觉表达不够专业&#xff1f;对于专科生来说&#xff0c;论文写作不仅是一项学术任务&#xff0c;更是一场与时间、精力和信心的较量。而如今&#xff0c;一款专为学生…

作者头像 李华
网站建设 2026/4/30 15:54:08

基于RGB颜色分量的人民币面值识别系统

- 标题&#xff1a;基于RGB颜色分量的人民币面值识别系统 - 关键词&#xff1a;matlab GUI 数字图像处理 RGB 旋转矫正 需要区域提取 形态学操作 颜色空间 - 步骤&#xff1a;打开图片 灰度化 边缘检测 旋转矫正 形态学操作 图像聚类 截取ROI 对原图旋转矫正 再颜色空间转换 再…

作者头像 李华
网站建设 2026/4/23 10:44:54

水性漆涂料废水处理工艺

随着环保法规趋严&#xff0c;水性漆因低VOC、高安全性广泛应用于各行业&#xff0c;但涂料废水处理问题日益突出。且成分复杂、处理难度大&#xff0c;若直接排放会严重污染水体&#xff0c;违背绿色生产理念。本文聚焦水性漆相关涂料废水&#xff0c;详解其特性与科学处理工艺…

作者头像 李华