如何使用PHP实现嵌套文件夹上传至数据库及存储读取操作?
PHP实现多级文件夹上传数据库解决方案
完全可以实现,以下是具体的实现逻辑和注意事项:
前置条件
- 前端使用HTML5原生的目录选择能力,无需额外依赖
- 数据库支持BLOB类型字段存储文件二进制内容(主流MySQL、PostgreSQL等都满足要求)
- PHP版本建议8.1及以上,可直接读取上传文件的完整相对路径
核心实现步骤
1. 前端目录上传配置
给文件选择框添加webkitdirectory属性即可支持选择整个文件夹,浏览器会自动递归读取所有子文件和对应层级路径:
<form action="upload.php" method="post" enctype="multipart/form-data"> <input type="file" name="files[]" webkitdirectory multiple> <button type="submit">上传文件夹</button> </form>
2. 数据库表结构设计
建议分两张表存储,兼顾结构清晰和读写效率:
- 目录结构表:维护文件夹的层级关系
字段名 类型 说明 dir_id int 主键,目录ID parent_dir_id int 父目录ID,根目录为0 dir_name varchar 目录名称 create_time datetime 创建时间 - 文件存储表:存储文件内容和关联关系
字段名 类型 说明 file_id int 主键,文件ID dir_id int 所属目录ID,关联目录结构表 file_name varchar 文件名称 file_content longblob 文件二进制内容 file_size int 文件大小(单位字节) mime_type varchar 文件MIME类型 upload_time datetime 上传时间
3. PHP后端上传处理逻辑
- 遍历
$_FILES['files']获取所有上传文件,PHP 8.1+可直接读取full_path字段拿到文件的相对路径(比如一级目录/二级目录/测试.txt) - 拆分相对路径得到各级目录名和最终文件名,递归查询/创建对应的目录记录,拿到文件所属的最终目录ID
- 读取上传文件的临时文件内容,和文件名、目录ID、大小等元信息一起写入文件存储表
// 简易处理示例 foreach ($_FILES['files']['tmp_name'] as $key => $tmpPath) { $relativePath = $_FILES['files']['full_path'][$key]; $pathParts = pathinfo($relativePath); $dirPath = $pathParts['dirname']; $fileName = $pathParts['basename']; // 自定义递归函数:解析$dirPath,创建/查询对应的目录ID $dirId = getOrCreateDir($dirPath); // 读取文件二进制内容 $fileContent = file_get_contents($tmpPath); // 写入数据库,此处省略PDO预处理操作 saveFileToDb($dirId, $fileName, $fileContent, filesize($tmpPath), mime_content_type($tmpPath)); }
4. 目录读取还原逻辑
- 从目录结构表递归查询得到完整的目录树结构
- 按目录ID关联查询对应目录下的所有文件
- 如果需要下载完整文件夹,可在服务端用
ZipArchive类按原目录结构生成压缩包输出给用户;如果是在线预览,直接按目录树渲染菜单,点击文件时读取file_content字段输出对应内容即可。
注意事项
- 提前修改
php.ini配置,调整upload_max_filesize、post_max_size、max_file_uploads参数,避免多文件/大文件上传被拦截 - 如果存储的文件数量多、体积大,不建议直接把二进制内容存在数据库,可改为将文件存在磁盘/对象存储,数据库只存目录结构、文件元信息和文件的实际存储路径,性能会高很多
- 必须做文件类型白名单校验,避免恶意脚本上传后被执行造成安全风险
内容的提问来源于stack exchange,提问作者BabyFly
相关产品推荐
相关产品推荐

