当前位置: 首页 > news >正文

php:实现压缩文件上传、解压、文件更名、压缩包删除功能

效果图

1.上传文件

2.压缩包文件

3.itemno1文件

4.上传到系统路径\ItemNo

5.更名后的itemno1文件(命名:当天日期+六位随机数)

代码

<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8'); ?>" method='post' enctype='multipart/form-data'><input type='hidden' name='FormID' value="<?php echo $_SESSION['FormID']; ?>"><input type='file' name='folderArchive[]' accept='.zip' multiple><input type='submit' value='上传' name='update'>
</form><!-- 三层结构: zip->文件夹->料号文件夹->料号文件 -->
<!-- 二层结构: zip->料号文件夹->料号文件 -->
<?php
//指定路径
$target_dir = 'ItemNo/';
// 临时解压目录( 新建后会被删除 )
$unpack_dir = 'ItemNo_Updates/';
//开始上传
if (isset($_POST['update'])) {// 判断是否有上传的文件if (isset($_FILES['folderArchive']) && !empty($_FILES['folderArchive']['name'])) {//设定一个变量,值为上传的文件信息$zip_files = $_FILES['folderArchive'];//对上传的文件的name值( 例如test.zip )进行遍历foreach ($zip_files['name'] as $key => $file_name) {//检验文件是否是zip文件// pathinfo() 函数用于解析路径信息:PATHINFO_EXTENSION参数,表明它会返回文件路径中的扩展名部分(如zip、txt 等)// 将 pathinfo() 返回的扩展名转换为小写形式,if (strtolower(pathinfo($file_name, PATHINFO_EXTENSION)) !== 'zip') {// sprintf 函数:格式化字符串输出的函数prnMsg(sprintf(_('文件 "%s" 不是ZIP格式,请上传ZIP文件.'), $file_name), 'error');// 如果不是zip文件就,跳过此文件( 将不再做上传等操作 ),继续执行后面的上传文件continue;}//判断每一条数据的error值:看是否上传成功( UPLOAD_ERR_OK表示长传成功 )if ($zip_files['error'][$key] === UPLOAD_ERR_OK) {//取出该条数据的tmp_name值( 获取上传文件的临时存储路径 )$temp_file = $zip_files['tmp_name'][$key];// 先创建并打开 ZipArchive 对象,创建一个新的ZipArchive对象(ZipArchive用于读取、创建、更新和提取ZIP格式的压缩文件)$zip = new ZipArchive;//打开压缩文件if ($zip->open($temp_file) === TRUE) {//创建临时解压目录mkdir($unpack_dir, 0755, true);// 验证ZIP文件结构//设置一个变量用于判断结构是否合规$structure_valid = true;//遍历ZipArchive对象(通过 $zip 引用)中的所有文件.numFiles是压缩包内的文件数量for ($i = 0; $i < $zip->numFiles && $structure_valid; $i++) {// 获取指定索引 $i 处的ZIP压缩包内文件的名称$filename = $zip->getNameIndex($i);//将返回一个数组,数组中的每个元素对应于字符串中两个斜杠(/)之间的部分$path_parts = explode('/', $filename);// 检查文件路径分隔符个数,必须是两层结构if (count($path_parts) != 2 && count($path_parts) != 3) {//如果不是两层结构,结构不正确$structure_valid = false;prnMsg(sprintf(_('文件 "%s" 的内部结构不符合要求.'), $file_name), 'error');// prnMsg( sprintf( _( '文件 "%s" 的内部结构不符合要求(必须是 ZIP -> (一级目录) -> 文件 的结构,至少要有一级子目录).' ), $file_name ), 'error' );//跳出循环break;}}//如果结构正确if ($structure_valid) {// 解压缩文件$zip->extractTo($unpack_dir);// 关闭已经打开的 ZipArchive 对象的( 与open对应 )$zip->close();// 寻找解压后的一级子目录(不论外部文件夹是否存在)$subDirs = [];// 定义递归函数,找出所有一级子目录function findSubDirs($dir, &$subDirs){foreach (glob($dir . '/*', GLOB_ONLYDIR) as $subDir) {// 如果当前目录下还有子目录且子目录下包含文件,则认定为一级子目录if (count(glob($subDir . '/*')) > 0 && count(glob($subDir . '/*', GLOB_ONLYDIR)) == 0) {$subDirs[] = $subDir;} else {// 继续递归寻找下一级子目录findSubDirs($subDir, $subDirs);}}}foreach (glob($unpack_dir . '/*', GLOB_ONLYDIR) as $possibleOuterDir) {// 直接处理一级子目录(ZIP -> 一级子目录 -> 文件结构)if (count(glob($possibleOuterDir . '/*', GLOB_ONLYDIR)) == 0) {$subDirs[] = $possibleOuterDir;} else {// 递归寻找可能的外部文件夹下的一级子目录findSubDirs($possibleOuterDir, $subDirs);}}//遍历每个文件夹的文件foreach ($subDirs as $subDir) {// 获取料号名称( 文件夹名称 )$itemNo = basename($subDir);// 获取子文件夹中的所有文件$temp_sub_dir_files = glob($subDir . '/*');//循环子文件中的文件foreach ($temp_sub_dir_files as $file) {// 如果 $file 是一个目录,跳过if (is_dir($file)) {continue;}//验证文件是否已在目标目录中存在//获取文件名称$fileName = basename($file);// 获取目标目录下所有文件和目录的名字$existingFiles = scandir($target_dir);// 如果文件不在目标目录现存文件列表中,则是新上传的文件if (!in_array($fileName, $existingFiles)) {//获取当前日期$dateForFilename = date('Ymd');//生成随机数$random_number = generateUniqueRandomNumber($target_dir, $dateForFilename);// 构建新的文件名YMD_六位随机数( pathinfo用于从文件路径 $file 中提取出文件扩展名。 )$newFileName = $dateForFilename . '_' . sprintf('%06d', $random_number) . '.' . pathinfo($file, PATHINFO_EXTENSION);//新文件路径$new_path = $subDir . '/' . $newFileName;// 重命名文件rename($file, $new_path);// $target_dir 是一个变量,它包含了目标目录的完整路径。// $itemNo 是另一个变量,它代表了要创建的子目录的名称或者是某种项目的唯一标识符。$targetSubDir = $target_dir . $itemNo;// 检查 $targetSubDir 是否已经存在且是一个目录if (!is_dir($targetSubDir)) {// 调用 mkdir() 函数尝试创建这个子目录// 第一个参数是待创建目录的路径名,即 $targetSubDir。// 第二个参数 0755 是指创建的目录的权限模式。这是一个八进制数,转换成二进制后表示所有者有读写执行权限,同组用户和其他用户有读和执行权限,但没有写入权限。// 第三个参数 true 表示如果父级目录不存在,也将递归创建它们(即允许创建多级目录)。mkdir($targetSubDir, 0755, true);}// 将处理完的文件移动到最终目标目录rename($new_path, $targetSubDir . '/' . $newFileName);// 插入数据库$time = time();//获取文件名称(去掉后缀)$baseNameWithoutExt1 = pathinfo($new_path, PATHINFO_FILENAME);// 检查assembly_item_no是否存在$sql_check = "SELECT COUNT(*) as count FROM bom_headers_all WHERE assembly_item_no = '" . $itemNo . "'";$result_check = DB_query($sql_check, $db);$row_check = DB_fetch_array($result_check);if ($row_check['count'] > 0) {// 如果记录已存在,则更新last_update_date$sql_update = "UPDATE bom_headers_all SET last_update_date = '" . $time . "',last_updated_by = '" . $_SESSION['UserID'] . "'  WHERE assembly_item_no = '" . $itemNo . "'";$result_update = DB_query($sql_update, $db);} else {// 如果记录不存在,上传到料号文件头$sql_insert = "INSERT INTO bom_headers_all (assembly_item_no,last_update_date,last_updated_by,creation_date,created_by)VALUES ('" . $itemNo . "','" . $time . "','" . $_SESSION['UserID'] . "','" . $time . "','" . $_SESSION['UserID'] . "')";$result_insert = DB_query($sql_insert, $db);}//查询该条料号的id$sql_selid = "SELECT bom_header_id FROM bom_headers_all WHERE assembly_item_no = '" . $itemNo . "'";$result_selid = DB_query($sql_selid, $db);if (DB_num_rows($result_selid) > 0) {// 获取第一条记录的bom_header_id$row_selid = mysqli_fetch_assoc($result_selid);$bom_header_id = $row_selid['bom_header_id'];//上传到料号文件行$sql_insert1 = "INSERT INTO bom_headers_all_file(bom_header_id,file_name,file_desc,file_patch,creation_date,created_by,last_update_by,last_update_date,enable_flag)VALUES ('" . $bom_header_id . "','" . '新文件名:' . $newFileName . "','" . '文件名:' . $fileName . "','" . $targetSubDir . '/' . $newFileName . "','" . $time . "','" . $_SESSION['UserID'] . "','" . $_SESSION['UserID'] . "','" . $time . "','Y')";$result_insert1 = DB_query($sql_insert1, $db);// prnMsg( sprintf( _( '文件 "%s" 在料号 "%s" 下已成功上传并重命名为 "%s" 并已插入数据库.' ), basename( $file ), $itemNo, $newFileName ), 'success' );} else {prnMsg('未获取到相应料号', 'error');}}}}// 删除临时解压目录及其内容delTree($unpack_dir);prnMsg(sprintf(_('文件 "%s" 上传成功.'), $file_name), 'success');} else {// 结构不合法,关闭ZIP资源并删除临时解压目录$zip->close();delTree($unpack_dir);continue;// 跳过该文件,进入下一个文件的处理}} else {prnMsg(sprintf(_('文件 "%s" 上传成功但无法解压.'), $file_name), 'error');}} else {prnMsg(sprintf(_('文件 "%s" 上传失败.'), $file_name), 'error');}}unset($_POST['update']);} else {prnMsg(_('附件上传失败!'), 'error');}
}// 定义一个函数,生成当天内不重复的六位随机数function generateUniqueRandomNumber($dir, $dateForFilename)
{//用do-while循环去判断文件名是否存在,如果存在就在此循环直到不存在为止do {// 生成一个介于100000到999999之间的随机整数$random_number = mt_rand(100000, 999999);//拼接字符串( /path/YMD_123456.ext 的字符串 )( .ext 是一个占位符,表示文件的扩展名,实际应用中应替换为具体的文件类型如 .jpg, .txt, .pdf 等。 )$filePath = $dir . '/' . $dateForFilename . '_' . sprintf('%06d', $random_number) . '.ext';} while (file_exists($filePath));//检查指定的文件路径 $filePath 是否存在。//跳出循环后返回随机数return $random_number;
}// 定义一个递归删除目录及其内容的函数function delTree($dir)
{// array_diff( scandir( $dir ), array( '.', '..' ) ) 从上述数组中排除.// (当前目录)和 ..(上级目录),得到的就是该目录下所有实际的文件和子目录名称,然后将其赋值给 $files。$files = array_diff(scandir($dir), array('.', '..'));// 使用 foreach 循环遍历 $files 数组中的每一个文件或子目录foreach ($files as $file) {// ( is_dir( "$dir/$file" ) ) 判断当前 $file 是否为子目录。// 如果 $file 是子目录,则调用 delTree( "$dir/$file" ) 函数递归删除这个子目录及其内部的所有文件和子目录。// 如果 $file 不是子目录(即普通文件),则调用 unlink( "$dir/$file" ) 函数删除这个文件。(is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");}//  删除最初传入的 $dir 目录本身。注意,只有当该目录为空时,rmdir() 才能成功删除目录。return rmdir($dir);
}
?>

相关文章:

php:实现压缩文件上传、解压、文件更名、压缩包删除功能

效果图 1.上传文件 2.压缩包文件 3.itemno1文件 或 4.上传到系统路径\ItemNo 5.更名后的itemno1文件(命名&#xff1a;当天日期六位随机数) 代码 <form action"<?php echo htmlspecialchars($_SERVER[PHP_SELF], ENT_QUOTES, UTF-8); ?>" methodpost en…...

【机器学习】科学库使用第5篇:Matplotlib,学习目标【附代码文档】

机器学习&#xff08;科学计算库&#xff09;完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;机器学习&#xff08;常用科学计算库的使用&#xff09;基础定位、目标&#xff0c;机器学习概述定位,目标,学习目标,学习目标,1 人工智能应用场景,2 人工智能小…...

Java面试八股文(JVM篇)(❤❤)

Java面试八股文_JVM篇 1、知识点汇总2、知识点详解&#xff1a;3、说说类加载与卸载11、说说Java对象创建过程12、知道类的生命周期吗&#xff1f;14、如何判断对象可以被回收&#xff1f;17、调优命令有哪些&#xff1f;18、常见调优工具有哪些20、你知道哪些JVM性能调优参数&…...

「51媒体」如何有效进行媒体邀约,提升宣传传播效果?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 进行有效的媒体邀约&#xff0c;提升宣传传播效果的关键在于策略性和专业性。以下是具体的做法&#xff1a; 明确目标&#xff1a;要确立清晰的品牌推广目标和策略&#xff0c;包括确定目…...

docker初始化进程

docker run --init 是一个 Docker 命令的选项&#xff0c;用于在容器中运行一个初始化进程&#xff08;通常是 tini&#xff09;。这个初始化进程负责处理一些 Unix 信号&#xff08;如 SIGTERM 和 SIGCHLD&#xff09;&#xff0c;并确保容器中的进程能够正确地被管理和清理。…...

基于快照行情的股票/基金 1分钟 K 线合成指南

1. 概述 由于不同交易所不同资产的交易规则是有差异的&#xff0c;导致不同交易所基于快照行情或逐笔成交合成不同资产1分钟 K 线的计算方法是不同的。 本教程旨在提高 DolphinDB 在具体业务场景下的落地效率&#xff0c;降低 DolphinDB 在实际业务使用中的开发难度。 本教程…...

新质生产力崛起:精益化能力助力企业转型升级

在智能制造、物联网、大数据、大模型、AI风起云涌的时代背景下&#xff0c;一个崭新的概念——“新质生产力”逐渐进入了人们的视野。这一热词不仅成为今年两会的讨论焦点&#xff0c;更代表了企业、国家乃至社会未来发展的核心动能。那么&#xff0c;什么是新质生产力&#xf…...

开发了一个在线客服系统

开发了一个在线客服系统 作为程序员&#xff0c;我一直在寻找能够提高工作效率和用户体验的方法。最近&#xff0c;我成功开发了一个在线客服系统&#xff0c;这个系统旨在帮助企业更高效地管理客户咨询和服务流程。 技术栈 我选择了以下的技术栈来构建这个系统&#xff1a;…...

cowa新的数据筛选代码

cowa新的数据筛选代码 代码地址&#xff1a; https://git.cowarobot.com/lhb/data_extracting 一阶段筛选 修改配置文件 config/common_stage.yamlversion: 3 services:de:image: harbor.cowarobot.cn/lhb/data:crpilot2.5-torch2.2environment:- CRPILOT_INSTALL_VERSIONx86…...

项目篇 | 图书管理系统 | 管理员模块 | 图书管理 | 删除

项目篇 | 图书管理系统 | 管理员模块 | 图书管理 | 删除 概述 图书管理页通过列表展示所有图书的相关信息,集成了搜索、添加、删除、修改的功能。 函数简介 // admin.h void delBook(); // 删除图书 void openDelBookMessage(); // 打开删除图书弹框 void closeDelBookMessa…...

自己动手封装axios通用方法并上传至私有npm仓库:详细步骤与实现指南

文章目录 一、构建方法1、api/request.js2、api/requestHandler.js3、api/index.js 二、测试方法1、api/axios.js2、main.js3、app.vue4、vue.config.js5、index.html 三、打包1、配置package.json2、生成库包3、配置发布信息4、发布 四、使用1、安装2、使用 五、维护1、维护和…...

【Sql Server】锁表如何解锁,模拟会话事务方式锁定一个表然后进行解锁

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》。 这是《Sql Server》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言创建表模拟…...

【大语言模型】轻松本地部署Stable Diffusion

硬件要求&#xff1a; 配备至少8GB VRAM的GPU&#xff0c;如果你的电脑只有CPU&#xff0c;请看到最后。根据部署规模&#xff0c;需要足够的CPU和RAM。 软件要求&#xff1a; Python 3.7或更高版本。支持NVIDIA GPU的PyTorch。Hugging Face的Diffusers库。Hugging Face的Tr…...

【github主页】优化简历

【github主页】优化简历 写在最前面一、新建秘密仓库二、插件卡片配置1、仓库状态统计2、Most used languages&#xff08;GitHub 常用语言统计&#xff09;使用细则 3、Visitor Badge&#xff08;GitHub 访客徽章&#xff09;4、社交统计5、打字特效6、省略展示小猫 &#x1f…...

dnspy逆向和de4dot脱壳

拿到一个软件&#xff0c;使用dnspy查看&#xff0c;发现反汇编后关键部分的函数名和代码有很多乱码&#xff1a; 这样的函数非常多&#xff0c;要想进一步调试和逆向&#xff0c;就只能在dnspy中看反汇编代码了&#xff0c;而无法看到c#代码&#xff0c;当时的整个逆向过程只剩…...

python之flask安装以及使用

1 flask介绍 Flask是一个非常小的Python Web框架&#xff0c;被称为微型框架&#xff1b;只提供了一个稳健的核心&#xff0c;其他功能全部是通过扩展实现的&#xff1b;意思就是我们可以根据项目的需要量身定制&#xff0c;也意味着我们需要学习各种扩展库的使用。 2 python…...

汽车笔记-保险

保险 1.交强险 上路必须买的&#xff0c; 国家规定必须要买。交强险不管你是有责还是无责&#xff0c;它都是可以赔偿的。交强险还有一个18000的垫付功能&#xff0c;比如说我们出了交通事故后&#xff0c;对方住院治疗需要你垫付钱&#xff0c;那么这个时候就可以用到交强险…...

人工智能时代的图像识别:机遇与挑战并存

人工智能&#xff08;AI&#xff09;时代为图像识别领域带来了前所未有的机遇&#xff0c;同时也伴随着一系列挑战。这一领域的发展不仅深刻影响了科技、医疗、教育、娱乐等多个行业&#xff0c;还在一定程度上改变了人们的生活方式。 机遇&#xff1a; 技术突破与创新&#…...

工作 9 年后,回老家当计算机老师的真实感受

北京某程序员发帖&#xff0c;他说自己工作了整整 9 年后&#xff0c;今年六月就告别了北京这个大都市&#xff0c;安安心心地回老家当起了计算机老师。 工作日&#xff0c;每天早上 8 点就得按点上班儿&#xff0c;到了下午 4 点半&#xff0c;下班儿的铃声一响&#xff0c;就…...

二叉树的镜像【c++】

#include <iostream> #include <vector> using namespace std;//双链表节点结构 typedef struct treeNode {int value;struct treeNode* left;struct treeNode* right;treeNode(int x) : value(x), left(nullptr), right(nullptr) {} } TreeNode;void mirrorTree(T…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...