PHP网页端大文件断点续传的代码怎么编写?
作为浙江的一名独立开发者,近期接到一个企业级需求:开发一套支持20GB大文件传输的系统,需兼容全平台(Windows/macOS/Linux)和全浏览器(含IE8),并实现文件夹层级结构保留的上传下载功能。经过一周的调研与实战,现将关键技术方案和代码片段整理如下,供同行参考。directorychunked${${round100$md5$md5$i$md5$iFormDataputObject:
开发者日记:WebUploader大文件传输系统开发实录
日期:2023年11月15日
天气:晴
作为浙江的一名独立开发者,近期接到一个企业级需求:开发一套支持20GB大文件传输的系统,需兼容全平台(Windows/macOS/Linux)和全浏览器(含IE8),并实现文件夹层级结构保留的上传下载功能。经过一周的调研与实战,现将关键技术方案和代码片段整理如下,供同行参考。
一、技术选型与架构设计
-
前端框架
- Vue3 CLI + WebUploader(百度开源组件)
- 兼容性处理:通过
@babel/polyfill和webuploader.flashonly.js支持IE8 - 文件夹上传:利用WebUploader的
directory属性结合HTML5 File System API
-
后端架构
- PHP 8.1 + Swoole(异步IO处理大文件)
- 分片上传:基于WebUploader的
chunked模式,每片5MB - 秒传实现:通过MD5校验文件唯一性
-
存储方案
- 阿里云OSS/华为云OBS双活架构
- 本地MySQL记录元数据(文件路径、分片信息、MD5等)
二、核心代码实现
1. 前端配置(Vue3组件)
// src/components/Uploader.vue
import WebUploader from 'webuploader';
import 'webuploader/dist/webuploader.css';
export default {
mounted() {
const uploader = WebUploader.create({
swf: '/static/Uploader.swf', // IE8兼容
server: '/api/upload',
pick: '#picker',
accept: {
title: 'All',
extensions: '*',
mimeTypes: '*'
},
compress: false,
chunked: true,
chunkSize: 5 * 1024 * 1024, // 5MB分片
threads: 4, // 并发数
formData: {
dir: '/uploads' // 默认存储路径
},
// 文件夹上传关键配置
directory: true,
disableGlobalDnd: true
});
// 监听文件添加(包含文件夹)
uploader.on('filesQueued', (files) => {
files.forEach(file => {
if (file.relativePath) { // 文件夹层级处理
console.log('Folder path:', file.relativePath);
}
});
uploader.upload();
});
// 进度监控
uploader.on('uploadProgress', (file, percentage) => {
console.log(`${file.name} 上传进度: ${Math.round(percentage * 100)}%`);
});
}
};
2. 后端处理(PHP + Swoole)
// api/upload.php
prepare("INSERT INTO chunks (md5, chunk_index, path) VALUES (?, ?, ?)");
$stmt->execute([$md5, $chunk, $tmpFile]);
// 所有分片上传完成后合并
if ($chunk === $chunks - 1) {
$finalPath = "/uploads/{$relativePath}" . basename($_POST['name']);
$mergedFile = "/tmp/{$md5}_merged";
// 合并分片(需根据实际存储方案调整)
for ($i = 0; $i < $chunks; $i++) {
file_put_contents($mergedFile, file_get_contents("/tmp/{$md5}_{$i}"), FILE_APPEND);
}
// 上传至阿里云
$ossClient->putObject('your-bucket', $finalPath, fopen($mergedFile, 'rb'));
// 清理临时文件
unlink($mergedFile);
for ($i = 0; $i < $chunks; $i++) unlink("/tmp/{$md5}_{$i}");
echo json_encode(['status' => 'success', 'path' => $finalPath]);
}
}
3. MySQL表设计
CREATE TABLE `chunks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`md5` varchar(32) NOT NULL COMMENT '文件唯一标识',
`chunk_index` int(11) NOT NULL COMMENT '分片索引',
`path` varchar(512) NOT NULL COMMENT '分片存储路径',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `md5_chunk` (`md5`, `chunk_index`)
) ENGINE=InnoDB;
三、关键问题解决
-
IE8兼容性
- 必须引入Flash版本的WebUploader(
webuploader.flashonly.js) - 禁用HTML5的
FormData,改用隐藏iframe提交
- 必须引入Flash版本的WebUploader(
-
文件夹层级保留
- 前端通过
file.relativePath获取完整路径 - 后端需解析路径并递归创建云存储目录(如阿里云的
putObject需指定完整路径)
- 前端通过
-
大文件断点续传
- 前端记录已上传分片索引
- 后端MySQL查询缺失分片,返回
skip_upload: true
四、后续优化计划
- 增加WebSocket实时进度推送
- 实现多云存储负载均衡
- 开发管理后台(基于Vue3 + Element Plus)
寻求帮助:目前文件夹上传在Safari浏览器存在路径解析异常,欢迎大神加入QQ群 374992201 指导调试!
今日进度:完成基础分片上传功能,明日将攻克文件夹跨浏览器兼容性问题。
(签名)
浙江独立开发者 · 林默
2023年11月15日 夜
附:完整项目地址
GitHub(待开源):https://github.com/your-repo/webuploader-pro
技术文档:项目根目录/docs/文件夹内
安装环境
PHP:7.2.14
调整块大小

NOSQL
NOSQL不需要任何配置,可以直接访问测试
SQL
创建数据库
您可以直接复制脚本进行创建

配置数据库连接

安装依赖

访问页面进行测试

数据表中的数据

效果预览
文件上传

文件刷新续传
支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传
文件夹上传
支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。
免费下载示例
更多推荐



所有评论(0)