news 2026/4/30 8:08:39

国企系统中,PHP如何实现大文件的切片上传示例?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
国企系统中,PHP如何实现大文件的切片上传示例?

一个苦逼信息安全专业学生的毕业设计求助

大家好,我是广西某高校信息安全专业的大三狗,眼瞅着就要毕业了,现在正被一个文件管理系统的毕业设计折磨得死去活来…

我的困境

最近遇到了一个"大"问题 - 不是大姨妈,是大文件上传!要求支持10G左右的文件传输,还要加密传输和存储,带断点续传,断点续传还得支持离线保存进度(关机重启都不丢那种)。文件夹上传还得保持层级结构,最好还能加密。

最可怕的是,要求支持IE8和国产浏览器!学校的老古董电脑还在用Windows 7+IE9…这年头还有人用IE8吗?我连IE11都想卸载!

技术栈

后端:PHP (Zend Studio)
前端:Vue3 CLI (原生JS实现)
数据库:MySQL
服务器:阿里云ECS (目前在本地CentOS虚拟机测试)
存储:阿里云OSS (私有云/公有云/混合云)

网上找代码的血泪史

网上的代码要么只有上传功能,要么文件夹上传残缺不全,都是片段代码根本不能用!最气人的是出了问题找不到人 - 这些开发者连个群都不建,更别提留联系方式了。我真的是服了!

求助各位大佬

有没有好心的大佬能免费指导我一下?最好能帮我把代码写好调试好,这样毕业答辩时我就能直接演示了!感恩戴德!

欢迎加入QQ群交流:374992201

最近群里做活动:

  • 新人加群送1~99元红包 (真的假的?)
  • 推荐项目有提成 (一个项目2万提1万,10个项目10万?这比打工强多了!)

PS:有没有师兄师姐能介绍工作啊?马上要毕业了,求推荐好工作!


代码实现方案

前端实现 (Vue3 + 原生JS)

// 文件切片上传核心逻辑classBigFileUploader{constructor(options){this.file=options.file;this.chunkSize=options.chunkSize||5*1024*1024;// 默认5MBthis.totalChunks=Math.ceil(this.file.size/this.chunkSize);this.currentChunk=0;this.uploadedChunks=this.loadProgress()||[];this.encryptKey=options.encryptKey;}// 从本地存储加载上传进度loadProgress(){constprogress=localStorage.getItem(`upload_${this.file.name}_progress`);returnprogress?JSON.parse(progress):[];}// 保存上传进度到本地存储saveProgress(){localStorage.setItem(`upload_${this.file.name}_progress`,JSON.stringify(this.uploadedChunks));}// 加密切片asyncencryptChunk(chunk){if(!this.encryptKey)returnchunk;// 这里使用Web Crypto API进行加密// 实际项目中应该使用更安全的加密方案constencoder=newTextEncoder();constkeyMaterial=awaitwindow.crypto.subtle.importKey('raw',encoder.encode(this.encryptKey),{name:'AES-GCM'},false,['encrypt']);constiv=window.crypto.getRandomValues(newUint8Array(12));constencrypted=awaitwindow.crypto.subtle.encrypt({name:'AES-GCM',iv:iv},keyMaterial,chunk);return{iv,encrypted};}// 上传单个切片asyncuploadChunk(chunkIndex){conststart=chunkIndex*this.chunkSize;constend=Math.min(start+this.chunkSize,this.file.size);constchunk=this.file.slice(start,end);// 加密切片constencrypted=awaitthis.encryptChunk(chunk);constformData=newFormData();formData.append('file',newBlob([encrypted.encrypted]));formData.append('chunkIndex',chunkIndex);formData.append('totalChunks',this.totalChunks);formData.append('fileName',this.file.name);formData.append('fileSize',this.file.size);formData.append('iv',encrypted.iv);try{constresponse=awaitfetch('/upload.php',{method:'POST',body:formData});if(response.ok){this.uploadedChunks.push(chunkIndex);this.saveProgress();returntrue;}returnfalse;}catch(error){console.error('上传失败:',error);returnfalse;}}// 开始上传asyncstartUpload(){// 先检查哪些切片已经上传过constchunksToUpload=[];for(leti=0;i<this.totalChunks;i++){if(!this.uploadedChunks.includes(i)){chunksToUpload.push(i);}}// 依次上传未完成的切片for(constchunkIndexofchunksToUpload){constsuccess=awaitthis.uploadChunk(chunkIndex);if(!success){console.error(`切片${chunkIndex}上传失败`);returnfalse;}this.currentChunk=chunkIndex;}// 所有切片上传完成,通知后端合并文件if(this.uploadedChunks.length===this.totalChunks){awaitthis.mergeFiles();localStorage.removeItem(`upload_${this.file.name}_progress`);returntrue;}returnfalse;}// 通知后端合并文件asyncmergeFiles(){try{constresponse=awaitfetch('/merge.php',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({fileName:this.file.name,totalChunks:this.totalChunks,encryptKey:this.encryptKey})});returnresponse.ok;}catch(error){console.error('合并文件失败:',error);returnfalse;}}}// 文件夹上传处理classFolderUploader{constructor(){this.folderStructure={};}// 处理文件夹上传asyncuploadFolder(files,basePath=''){constuploaders=[];for(constfileoffiles){constrelativePath=file.webkitRelativePath||file.relativePath;constfilePath=basePath?`${basePath}/${relativePath}`:relativePath;// 保存文件路径结构this.folderStructure[filePath]=file;// 创建大文件上传实例constuploader=newBigFileUploader({file:file,encryptKey:'your-secret-key'// 实际项目应该更安全地处理密钥});uploaders.push(uploader.startUpload());}// 等待所有文件上传完成constresults=awaitPromise.all(uploaders);returnresults.every(success=>success);}}

后端实现 (PHP)

'缺少必要参数']));}// 创建上传目录$uploadDir='uploads/'.md5($fileName);if(!is_dir($uploadDir)){mkdir($uploadDir,0777,true);}// 保存切片文件$chunkFile=$uploadDir.'/'.$fileName.'.part'.$chunkIndex;move_uploaded_file($_FILES['file']['tmp_name'],$chunkFile);// 保存切片元数据$metaFile=$uploadDir.'/meta.json';$metaData=file_exists($metaFile)?json_decode(file_get_contents($metaFile),true):[];$metaData['chunks'][]=$chunkIndex;$metaData['fileName']=$fileName;$metaData['fileSize']=$fileSize;$metaData['totalChunks']=$totalChunks;$metaData['iv']=$iv;// 保存初始化向量用于解密file_put_contents($metaFile,json_encode($metaData));echojson_encode(['success'=>true]);?>
'缺少必要参数']));}$uploadDir='uploads/'.md5($fileName);$metaFile=$uploadDir.'/meta.json';if(!file_exists($metaFile)){http_response_code(404);die(json_encode(['error'=>'找不到上传记录']));}$metaData=json_decode(file_get_contents($metaFile),true);// 检查是否所有切片都已上传if(count($metaData['chunks'])!==$totalChunks){http_response_code(400);die(json_encode(['error'=>'切片不完整']));}// 创建最终文件$finalPath='uploads/'.basename($fileName);$finalFile=fopen($finalPath,'wb');// 按顺序合并所有切片for($i=0;$i<$totalChunks;$i++){$chunkFile=$uploadDir.'/'.$fileName.'.part'.$i;$chunkData=file_get_contents($chunkFile);// 如果有加密密钥,则解密数据if($encryptKey&&isset($metaData['iv'])){// 这里应该实现解密逻辑// 实际项目中应该使用更安全的解密方案$chunkData=$this->decryptChunk($chunkData,$encryptKey,$metaData['iv']);}fwrite($finalFile,$chunkData);unlink($chunkFile);// 删除切片文件}fclose($finalFile);unlink($metaFile);// 删除元数据文件// 如果需要存储到阿里云OSS$this->uploadToOSS($finalPath);echojson_encode(['success'=>true,'path'=>$finalPath]);functiondecryptChunk($encryptedData,$key,$iv){// 这里实现解密逻辑// 实际项目中应该使用更安全的实现return$encryptedData;// 简化示例}functionuploadToOSS($filePath){// 实现阿里云OSS上传逻辑}?>

支持IE8的兼容方案

// IE8兼容性处理if(!window.localStorage){window.localStorage={_data:{},setItem:function(id,val){this._data[id]=String(val);// 使用cookie作为fallbackdocument.cookie=id+"="+encodeURIComponent(val)+"; path=/";},getItem:function(id){returnthis._data.hasOwnProperty(id)?this._data[id]:undefined;},removeItem:function(id){deletethis._data[id];document.cookie=id+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";},clear:function(){this._data={};// 清除所有cookie可能不实际,这里只是示例}};// 初始化时从cookie加载varcookies=document.cookie.split(';');for(vari=0;i<cookies.length;i++){varcookie=cookies[i].trim();vareqPos=cookie.indexOf('=');varname=eqPos>-1?cookie.substr(0,eqPos):cookie;localStorage._data[name]=decodeURIComponent(cookie.substr(eqPos+1));}}// File API 兼容性处理if(!window.File||!window.FileReader||!window.FileList||!window.Blob){alert('您的浏览器不支持HTML5 File API,请使用现代浏览器');}// FormData 兼容性处理if(!window.FormData){document.write('<\/script>');}

总结

这个方案实现了:

  1. 大文件分片上传
  2. 断点续传(使用localStorage保存进度)
  3. 简单的加密传输和存储
  4. 文件夹上传保留层级结构
  5. IE8+兼容性处理

当然,实际项目中还需要考虑更多安全性和性能优化问题。希望这个方案能帮助你完成毕业设计!

PS:关于工作推荐…要不你先把这项目做出来,这就是你最好的简历了!😂

安装环境

PHP:7.2.14

调整块大小

NOSQL

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

SQL

创建数据库

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

配置数据库连接

安装依赖

访问页面进行测试

数据表中的数据

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

免费下载示例

点击下载完整示例

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

当 AI 不再乱跑:一些以前做不了的事,开始变得可行

过去几年&#xff0c;AI 看起来无所不能&#xff0c;但真正落地时&#xff0c;很多人都有同一个感受&#xff1a; “好像什么都能试一试&#xff0c;但什么都不敢真的用。” 问题并不在模型能力&#xff0c;而在一个长期被忽略的事实&#xff1a; AI 一直处在“不可控运行态”。…

作者头像 李华
网站建设 2026/4/17 19:09:10

Deepoc具身模型开发板:半导体制造智能化的技术引擎

引言&#xff1a;半导体制造的智能化革命在摩尔定律逼近物理极限的今天&#xff0c;半导体制造正面临前所未有的挑战。制程工艺从7纳米向3纳米、2纳米迈进&#xff0c;工艺复杂度呈指数级增长&#xff0c;传统依赖人工经验和固定算法的制造模式已难以应对。Deepoc具身模型开发板…

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

蛋白质N端和C端的序列测定

蛋白质N端和C端的序列测定蛋白质的N端和C端序列测定&#xff0c;是指确定蛋白质链两端的氨基酸排列顺序。这两端的氨基酸序列对于蛋白质的功能及其在细胞内的定位与修饰有影响。蛋白质的结构和功能密切相关&#xff0c;而其序列则是理解其结构和功能的基础。在蛋白质功能研究中…

作者头像 李华
网站建设 2026/4/29 15:01:37

OpenCode + Antigravity Auth 插件完整使用教程

OpenCode Antigravity Auth 插件完整使用教程 本教程将详细介绍如何安装和配置 opencode-antigravity-auth 插件&#xff0c;使 OpenCode 能够通过 OAuth 认证访问 Google 的 Antigravity (Google 内部 IDE) 配额&#xff0c;从而使用 gemini-3-pro、claude-sonnet-4-5-think…

作者头像 李华
网站建设 2026/4/30 6:52:26

OpenCode + Oh My OpenCode 深度使用教程:开启智能体协作的“超频”模式

Oh My OpenCode 深度使用教程&#xff1a;开启智能体协作的“超频”模式 1. 简介 Oh My OpenCode (OMO) 是一款专为 OpenCode 打造的高级增强插件。它不仅仅是一个工具集&#xff0c;更是一套完整的“智能体工作流”。 通过 OMO&#xff0c;你的 OpenCode 将进化为一套能够并…

作者头像 李华
网站建设 2026/4/24 16:45:59

6.2 专业技能速成班:让AI成为你的行业专家导师

6.2 专业技能速成班:让AI成为你的行业专家导师 在快速变化的现代社会中,终身学习已成为个人职业发展的必要条件。无论是转行进入新领域,还是在现有岗位上提升专业技能,我们都需要不断学习新知识和掌握新技能。然而,传统的学习方式往往存在学习周期长、成本高、资源有限等…

作者头像 李华