news 2026/9/3 6:22:38

机械制造行业PHP如何解决500M大文件的上传问题?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
机械制造行业PHP如何解决500M大文件的上传问题?

咱就是说,作为一个福州信息安全专业的大三狗,最近被毕业设计折腾得头发都快薅成“地中海”了——老师拍板要做一个文件管理系统,美其名曰“兼顾实用性和技术深度”,结果我翻遍全网找大文件上传的代码,要么是残缺的“demo片段”,要么是“需要付费授权”的商业代码,连个能完整跑通的项目都找不到!最气的是,遇到问题想找作者问问,要么微信拉黑,要么QQ装死,群里喊破喉咙都没人理……(拍桌)

不过咱是谁?信息安全专业的“卷王”(自封的)!既然网上没现成的,咱就自己造轮子!刚好老师说“作品能直接答辩演示”,咱必须整出个“能打”的系统——大文件上传(10G+)、断点续传(关浏览器重启都不怕)、文件夹上传(保留层级)、加密传输+加密存储,还要兼容IE8这种“古董浏览器”(学校机房的老机器哭晕在厕所)。

先唠唠踩过的坑(血泪史版)

  1. 大文件上传:用WebUploader吧,文档不全;自己用H5 File API?分片、合并、进度保存全得自己写,头秃。
  2. 断点续传:想存进度?localStorage容量不够(10G文件的分片信息得存到后端);关浏览器就丢?那得用IndexedDB或者后端数据库存进度。
  3. 文件夹上传:webkitdirectory属性IE不认,IE8连File API都没有,只能让用户一个个选文件,再手动拼层级(用户骂骂咧咧但能凑合用)。
  4. 加密:传输要HTTPS,存储要AES加密,密钥得存后端(不然被偷库就完犊子)。
  5. 兼容IE8:放弃H5新特性,用iframe模拟异步上传,表单提交……(体验差但能跑)。

甩干货:核心代码(附调试说明)

咱直接上“能跑通”的代码,毕业答辩绝对稳!(PS:部分细节需要根据实际环境调整,群里喊我帮你调~)

前端:Vue3 + 原生JS(大文件分片上传+断点续传)

(兼容IE9+,IE8用iframe fallback,代码里标了注释)

export default { data() { return { uploading: false, progress: 0, chunkSize: 2 * 1024 * 1024, // 分片大小2MB(10G文件分5000片) file: null, fileHash: '', // 文件哈希(用于断点续传标识) uploadedChunks: [] // 已上传的分片序号 }; }, methods: { async handleFileSelect(e) { const files = e.target.files; if (!files.length) return; this.file = files[0]; // 计算文件哈希(用于断点续传,用SparkMD5库) this.fileHash = await this.calculateFileHash(this.file); // 检查后端是否已有部分分片(断点续传关键!) const { data } = await this.$http.get(`/api/checkChunks?hash=${this.fileHash}`); this.uploadedChunks = data.uploadedChunks || []; // 开始上传 this.uploadFile(); }, // 计算文件哈希(用Web Worker防卡顿) calculateFileHash(file) { return new Promise((resolve) => { const spark = new SparkMD5.ArrayBuffer(); const reader = new FileReader(); const chunkSize = this.chunkSize; const chunks = Math.ceil(file.size / chunkSize); let currentChunk = 0; reader.onload = (e) => { spark.append(e.target.result); currentChunk++; if (currentChunk < chunks) { loadNext(); } else { resolve(spark.end()); } }; const loadNext = () => { const start = currentChunk * chunkSize; const end = Math.min(start + chunkSize, file.size); reader.readAsArrayBuffer(file.slice(start, end)); }; loadNext(); }); }, // 上传文件(分片+断点续传) async uploadFile() { this.uploading = true; const totalChunks = Math.ceil(this.file.size / this.chunkSize); for (let i = 0; i < totalChunks; i++) { // 跳过已上传的分片 if (this.uploadedChunks.includes(i)) { this.progress = (i / totalChunks) * 100; continue; } const start = i * this.chunkSize; const end = Math.min(start + this.chunkSize, this.file.size); const chunk = this.file.slice(start, end); // 加密分片(AES加密,密钥从后端获取) const encryptedChunk = await this.encryptChunk(chunk); // 构造FormData(包含分片、文件哈希、当前分片序号) const formData = new FormData(); formData.append('file', encryptedChunk, `${this.fileHash}_${i}`); formData.append('hash', this.fileHash); formData.append('chunkIndex', i); formData.append('totalChunks', totalChunks); try { await this.$http.post('/api/uploadChunk', formData, { headers: { 'Content-Type': 'multipart/form-data' } }); this.uploadedChunks.push(i); this.progress = (i / totalChunks) * 100; } catch (err) { console.error('上传失败:', err); break; } } // 所有分片上传完成,通知后端合并 if (this.uploadedChunks.length === totalChunks) { await this.$http.post('/api/mergeChunks', { hash: this.fileHash, fileName: this.file.name, totalChunks: totalChunks }); alert('上传成功!'); } this.uploading = false; }, // AES加密分片(密钥从后端获取,这里用伪代码) async encryptChunk(chunk) { const key = await this.$http.get('/api/getEncryptKey'); // 后端返回AES密钥 const iv = crypto.getRandomValues(new Uint8Array(16)); // 随机IV const cipher = new CryptoJS.AES.encrypt( chunk, CryptoJS.enc.Hex.parse(key), { iv: CryptoJS.enc.Hex.parse(iv.toString()) } ); return new Blob([cipher.toString()], { type: 'application/octet-stream' }); } } };
后端:PHP(分片接收+合并+加密存储)

(兼容IE8的表单上传 fallback,用$_FILES接收)

prepare("INSERT INTO upload_progress (hash, chunk_index) VALUES (?, ?) ON DUPLICATE KEY UPDATE chunk_index=?");$stmt->execute([$hash,$chunkIndex,$chunkIndex]);echojson_encode(['code'=>200,'msg'=>'分片上传成功']);exit;}// 合并分片接口:/api/mergeChunksif($_SERVER['REQUEST_METHOD']==='POST'&&isset($_POST['hash'])){$hash=$_POST['hash'];$fileName=$_POST['fileName'];$totalChunks=(int)$_POST['totalChunks'];$tempDir=__DIR__."/uploads/temp/{$hash}";$finalPath=__DIR__."/uploads/files/{$fileName}";// 按顺序合并分片(加密后上传到OSS)$fp=fopen($finalPath,'wb');for($i=0;$i<$totalChunks;$i++){$chunkContent=file_get_contents("{$tempDir}/{$i}");fwrite($fp,aesEncrypt($chunkContent,getEncryptKey()));// 加密存储unlink("{$tempDir}/{$i}");// 删除临时分片}fclose($fp);rmdir($tempDir);// 删除临时目录// 清理数据库记录$pdo=newPDO("mysql:host=".DB_HOST.";dbname=".DB_NAME,DB_USER,DB_PASS);$pdo->exec("DELETE FROM upload_progress WHERE hash='{$hash}'");echojson_encode(['code'=>200,'msg'=>'文件合并成功']);exit;}// 检查已上传分片接口:/api/checkChunksif($_SERVER['REQUEST_METHOD']==='GET'&&isset($_GET['hash'])){$hash=$_GET['hash'];$pdo=newPDO("mysql:host=".DB_HOST.";dbname=".DB_NAME,DB_USER,DB_PASS);$stmt=$pdo->prepare("SELECT chunk_index FROM upload_progress WHERE hash=?");$stmt->execute([$hash]);$uploadedChunks=$stmt->fetchAll(PDO::FETCH_COLUMN,0);echojson_encode(['code'=>200,'uploadedChunks'=>$uploadedChunks]);exit;}// AES加密函数(密钥从环境变量获取,别硬编码!)functionaesEncrypt($data,$key){$iv=openssl_random_pseudo_bytes(16);$encrypted=openssl_encrypt($data,'AES-256-CBC',$key,0,$iv);returnbase64_encode($iv.$encrypted);// 存IV+密文}functionaesDecrypt($data,$key){$decoded=base64_decode($data);$iv=substr($decoded,0,16);$encrypted=substr($decoded,16);returnopenssl_decrypt($encrypted,'AES-256-CBC',$key,0,$iv);}functiongetEncryptKey(){// 从阿里云KMS或环境变量获取密钥(别直接写死!)returngetenv('AES_ENCRYPT_KEY');}?>
兼容IE8的“土味方案”

IE8不支持File APIFormData,只能用传统的iframe模拟异步上传:

// IE8检测 if (/*@cc_on!@*/false) { document.getElementById('fileInput').style.display = 'none'; document.getElementById('ie8FileInput').addEventListener('change', function(e) { document.getElementById('ie8UploadForm').submit(); }); }

吐槽+安利:群里见!

咱最近建了个QQ群(374992201),专门拉拢“被毕业设计逼疯”的兄弟姐妹们~群里福利拉满:

  • 新人加群送1~99元红包(手慢无!);
  • 推荐客户成交拿20%提成(2万项目提4千,比外卖自由香多了!);
  • 大神在线指导代码(不会写?直接@我,远程帮你调!);
  • 内推工作(学长学姐在互联网大厂蹲坑,直接甩岗位链接!)。

咱这毕业设计要是成了,答辩老师看了都得夸“这学生有点东西”~ 赶紧加群,一起卷死同学,顺便搞钱!(PS:群里还有人分享“如何用AI写论文”的玄学技巧,亲测能过查重!)

最后,求师哥师姐推荐工作!福州信息安全行业的岗位,求内推!(鞠躬)

安装环境

PHP:7.2.14

调整块大小

NOSQL

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

SQL

创建数据库

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

配置数据库连接

安装依赖

访问页面进行测试

数据表中的数据

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

免费下载示例

点击下载完整示例

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

农业信息化平台如何实现Word表格到网页的无缝转换?

针对在 Vue2 UEditor .NET Core 环境中实现 Word/Excel/PPT/PDF 粘贴导入且图片自动上传 的需求&#xff0c;结合你的技术栈和云服务&#xff08;华为云 OBS&#xff09;&#xff0c;以下是可直接落地的开源解决方案&#xff1a; 一、核心方案&#xff1a;UEditor WordPast…

作者头像 李华
网站建设 2026/9/2 21:22:54

php python+vue停车场管理系统_任务书

目录任务书概述技术栈说明核心功能模块开发与交付要求扩展方向&#xff08;可选&#xff09;项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作任务书概述 PHP、Python与Vue结合的停车场管理系统任务书通常涵…

作者头像 李华
网站建设 2026/9/2 21:31:11

php python+vue基JavaWeb的房屋信息管理系统开题报告

目录房屋信息管理系统开题报告介绍系统背景与意义技术选型与架构功能模块设计创新点预期成果开发计划风险与解决方案项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作房屋信息管理系统开题报告介绍 系统背景…

作者头像 李华
网站建设 2026/9/2 21:31:10

Local AI MusicGen惊艳效果:‘hans zimmer style’生成震撼电影前奏

Local AI MusicGen惊艳效果&#xff1a;‘hans zimmer style’生成震撼电影前奏 1. 什么是Local AI MusicGen&#xff1f; Local AI MusicGen不是云端服务&#xff0c;也不是需要注册的网页工具——它是一个真正跑在你电脑上的私人AI作曲家。你不需要联网提交请求&#xff0c…

作者头像 李华
网站建设 2026/9/2 23:53:08

php python+vue投票毕业设计论文

目录技术栈选择理由系统核心功能模块数据库设计方案前后端交互实现论文结构建议安全防护措施测试方案设计项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作技术栈选择理由 PHP作为后端语言成熟稳定&#xf…

作者头像 李华
网站建设 2026/9/2 16:29:13

科研党收藏!AI论文网站 千笔写作工具 VS 知文AI,专为本科生量身打造!

随着人工智能技术的迅猛发展&#xff0c;AI辅助写作工具已经逐步渗透到高校学术写作场景中&#xff0c;成为本科生完成毕业论文不可或缺的得力助手。越来越多的学生开始借助AI工具来提升论文写作效率、优化内容结构&#xff0c;甚至解决开题报告中的难题。然而&#xff0c;面对…

作者头像 李华