news 2026/3/8 14:10:05

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/3/4 9:04:04

军工项目文档管理如何适配UEDITOR的跨平台特性?

CMS企业官网项目需求分析与解决方案 大家好&#xff0c;我是安徽的一名.NET程序员&#xff0c;最近接了个CMS企业官网的外包项目。客户提出了一个新需求&#xff0c;要在后台新闻管理系统的文章发布模块编辑器中增加导入Word、Excel、PPT、PDF文档和Word一键粘贴功能。这需求听…

作者头像 李华
网站建设 2026/3/4 6:29:53

教育信息化如何通过百度编辑器实现课件PPT转HTML?

企业网站后台管理系统富文本编辑器Word集成解决方案评估与实施报告 项目负责人&#xff1a;XXX 日期&#xff1a;2023-XX-XX 一、需求背景分析 当前集团企业网站后台管理系统存在以下核心需求&#xff1a; 需要实现Word内容完美粘贴&#xff08;保留所有样式和特殊元素&…

作者头像 李华
网站建设 2026/3/4 7:46:30

医疗系统如何通过富文本编辑器实现DICOM图像转存?

广东某国企项目负责人技术选型与开发实施记录 一、需求背景与核心目标 为满足政府客户在企业网站后台管理系统升级需求&#xff0c;需在UEditor富文本编辑器中扩展三大功能&#xff1a; Word粘贴增强&#xff1a;支持图文混排、样式保留、图片自动上传至华为云OBSOffice文档…

作者头像 李华
网站建设 2026/3/3 7:19:40

MESCIUS PDF文档解决方案将多个文档合并成一个PDF文件

将多个文档合并成一个 PDF 文件 2026年2月6日将多个文档合并为一个 PDF 文件&#xff0c;以简化共享、提高组织效率并保持专业、美观的演示效果。MESCIUS 的PDF 文档解决方案在 PDF 查看器中合并 PDF 文件&#xff0c;用户无需借助外部工具&#xff0c;即可直接在查看应用程序中…

作者头像 李华
网站建设 2026/3/4 10:38:42

格子玻尔兹曼LBM三维GPU并行程序:d3q19的惊人加速

格子玻尔兹曼LBM三维GPU并行程序 d3q19可加速100-150倍最近在研究计算流体力学相关项目时&#xff0c;接触到了格子玻尔兹曼方法&#xff08;Lattice Boltzmann Method&#xff0c;LBM&#xff09;&#xff0c;尤其是其三维GPU并行程序&#xff0c;其中基于d3q19模型的实现带来…

作者头像 李华
网站建设 2026/3/4 7:54:48

写作压力小了!专科生专属AI论文神器 —— 千笔·专业学术智能体

你是否曾为论文选题发愁&#xff0c;反复修改却总对表达不满意&#xff1f;是否在查重和格式上耗费大量时间&#xff0c;却仍难达到要求&#xff1f;专科生的论文之路本就充满挑战&#xff0c;而如今&#xff0c;一款专为你们打造的AI论文神器——千笔AI&#xff0c;正悄然改变…

作者头像 李华