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><?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) {//如果不是两层结构,结构不正确$structure_valid = false;prnMsg(sprintf(_('文件 "%s" 的内部结构不符合要求(必须是 ZIP -> (一级目录) -> 文件 的结构,至少要有一级子目录).'), $file_name), 'error');//跳出循环break;}}//如果结构正确if ($structure_valid) {// 解压缩文件$zip->extractTo($unpack_dir);// 关闭已经打开的 ZipArchive 对象的(与open对应)$zip->close();// 获取解压后每个料号(子文件夹)的路径,取$target_dir目录下的所有子目录名称,并将这些名称作为一个数组赋值给$subDirs。// $target_dir . '*':表示匹配$target_dir目录下的任何子字符串(在这里实际上指的是子目录名)// GLOB_ONLYDIR 是 glob() 函数的一个标志参数,当设置这个标志时,glob() 函数只会返回与指定模式匹配的目录名$subDirs = glob($unpack_dir . '*', GLOB_ONLYDIR);//遍历每个文件夹的文件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();//获取文件名称(去掉后缀)$baseNameWithoutExt = pathinfo($new_path, PATHINFO_FILENAME);$sql = "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 ('1','" . $baseNameWithoutExt . "','" . $itemNo . "','" . $targetSubDir . '/' . $newFileName . "','" . $time . "','" . $_SESSION['UserID'] . "','" . $time . "','" . $_SESSION['UserID'] . "','Y')";$result = DB_query($sql, $db);// prnMsg(sprintf(_('文件 "%s" 在料号 "%s" 下已成功上传并重命名为 "%s" 并已插入数据库.'), basename($file), $itemNo, $newFileName), 'success');}}}// 删除临时解压目录及其内容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);
}
?>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/311374.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT基础(二) ChatGPT的使用和调优

文章目录 ChatGPT的特性采用关键词进行提问给ChatGPT指定身份提升问答质量的策略1.表述方式上的优化2.用"继续"输出长内容3.营造场景4.由浅入深&#xff0c;提升问题质量5.预设回答框架和风格 ChatGPT的特性 1.能够联系上下文进行回答 ChatGPT回答问题是有上下文的&…

Java --- 类与对象

上篇内容给大家带来了Java的语句与数组的相关内容&#xff0c;那么本期内容比较重要&#xff0c;需要读者们掌握Java面向对象编程的根本&#xff0c;通过这篇博客来让读者浅入理解Java类的一些基本操作。 目录 一.特点&#xff1a; 二.成员变量&#xff1a; 三.访问修饰符&a…

【JavaSE】搞定String类

前言 本篇会细致讲解String类的常见用法&#xff0c;让小伙伴们搞定String类~ 欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 前言 常用的三种字符串构造 字符串长度length 字符串比较 比较 比较字符串的内容equals…

「2024」React 状态管理入门

概念 简单来说&#xff0c;状态指的是某一时刻应用中的数据或界面的呈现。这些数据可能包括用户填写表单的信息、应用内的用户偏好设置、应用的页面/路由状态、或者任何其他可能改变UI的信息。 状态管理是前端开发中处理用户界面(UI)状态的过程&#xff0c;在复杂应用中尤其重…

【DA-CLIP】图像退化类型检测功能演示代码

背景 在CLIP基础上微调而来&#xff0c;使用图像控制器编码生成退化类型embedding并在训练中对图像编码器进行控制。针对十种退化类型进行了训练。 解决CLIP模型在图像纹理等层面无法针对退化类型识别或识别率较低的问题。 训练数据集情况 GitHub有对应数据集连接 完整代码 项…

HBase的数据模型与架构

官方文档&#xff1a;Apache HBase – Apache HBase™ Homehttps://hbase.apache.org/ 一、HBase概述 1.概述 HBase的技术源自Google的BigTable论文&#xff0c;HBase建立在Hadoop之上&#xff0c;是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统&#xff0c;用于…

工作流引擎项目解析

API 编辑 在Camunda中&#xff0c;API的继承关系主要体现在各个服务接口之间。以下是Camunda中一些常见服务接口的继承关系&#xff1a; ProcessEngineServices 接口&#xff1a; RepositoryService&#xff1a; 负责管理流程定义和部署。 RuntimeService&#xff1a; 负责管…

2024年nodejs调用小红书最新关注(粉丝)follow接口,api接口分析2004-04-16

一、打开chrome按f12&#xff0c;点击右上角的“关注”按钮&#xff0c;抓包位置如下&#xff1a; (图1 follow接口) 二、follow接口分析 1、请求地址 https://edith.xiaohongshu.com/api/sns/web/v1/user/follow 2、请求方法: POST 3、请求头&#xff1a; :authority: edith…

最新AI创作系统ChatGPT网站源码AI绘画,GPTs,AI换脸支持,GPT联网提问、DALL-E3文生图

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

25. 【Android教程】列表控件 ListView

在学习了 ScrollView 及 Adapter 两节内容之后&#xff0c;大家应该对 ListView 有了一些基本的了解&#xff0c;它是一个列表样式的 ViewGroup&#xff0c;将若干 item 按行排列。ListView 是一个很基本的控件也是 Android 中最重要的控件之一。它可以帮助我们完成多个 View 的…

Udio——革命性的AI音乐生成软件

Udio是一款革命性的AI音乐生成软件&#xff0c;由前谷歌DeepMind的顶尖AI研究人员和工程师共同创立&#xff0c;得到著名风险投资公司a16z的支持。它旨在为音乐爱好者和专业人士提供一个全新的音乐创作和分享平台。用户可以通过文本提示来生成音乐&#xff0c;支持广泛的音乐风…

水牛社:打造你的居家副业利器,让赚钱变得更简单

水牛社&#xff0c;这个已经陪伴我们走过九个春秋的综合性网络任务和项目资源整合平台&#xff0c;真的给我留下了深刻的印象。它不仅仅是一个资源的汇聚地&#xff0c;更是一个帮助无数人实现网络副业梦想的平台。作为一个资深用户&#xff0c;我深感其中的价值和魅力。 水牛…

“香港批准比特币、以太坊ETF”!华夏、博时、嘉实计划发行相关产品!美国ETF分析师泼冷水:别指望香港ETF会有很大流量!

周一(4月15日)&#xff0c;比特币短线迎来反弹行情&#xff0c;币价回升至66000美元上方。华夏基金、博时国际与嘉实投资3家中国头部基金宣布&#xff0c;旗下虚拟资产现货ETF获准在香港发行。 据了解&#xff0c;华夏基金&#xff08;香港&#xff09;现计划发行能够投资于现货…

两部电话机怎样能实现对讲?直接连接能互相通话吗?门卫门房传达室岗亭电话怎么搞?

目录 两部电话机能直接连接吗&#xff1f;用三通头分出来一条电话线两部电话机用一根电话线直接连接能互相通话吗&#xff1f; 什么电话机可以直接连接两部IP电话机&#xff08;网络电话机&#xff09;可以直接连接两部普通电话机之间通过一个电话交换机也可以连接跨区域的两部…

mfc 带有复选框的ListBox

mfc 带有复选框的 ListBox 效果&#xff1a; 添加 ListBox 控件 从工具箱拖拽 ListBox 控件到窗口上&#xff0c;并设置属性&#xff1a; 包含字符串&#xff1a;true所有者描述&#xff1a;Fixed 给ListBox添加控制变量 添加完后&#xff0c;将m_list_box的类型使用CC…

react使用npm i @reduxjs/toolkit react-redux

npm i reduxjs/toolkit react-redux 创建一个 store文件夹&#xff0c;里面创建index.js文件和子模块文件夹 index,js文件写入以下代码 import {configureStore} from reduxjs/toolkit // 导入子模块 import counterReducer from ./modules/one import two from ./modules/tw…

OpenBayes 在线教程|张国荣、鲁迅等老照片秒变高清!即刻上手的超火 SUPIR-AI 图像修复教程

小伙伴们&#xff0c;大家在生活中是不是也会遇到这样的烦恼&#xff1a;心心念念想要打印一张充满回忆的老照片或酷炫动漫壁纸&#xff0c;却发现图像糊得像打了马赛克&#xff1f; 市面上的图像修复工具五花八门&#xff0c;选择困难症人群找得快要崩溃&#xff1f; 终于找…

Linux: softirq 简介

文章目录 1. 前言2. softirq 实现2.1 softirq 初始化2.1.1 注册各类 softirq 处理接口2.1.2 创建 softirq 处理线程 2.2 softirq 的 触发 和 处理2.1.1 softirq 触发2.1.2 softirq 处理2.1.2.1 在 中断上下文 处理 softirq2.1.2.2 在 ksoftirqd 内核线程上下文 处理 softirq 3.…

电子烟特效音语音方案选型-WTN6020-8S-E

随着科技的迅猛进步&#xff0c;电子烟行业亦在持续创新与突破&#xff0c;引领着全新的潮流。其中&#xff0c;电子烟产品所特有的吸烟声音特效播报功能&#xff0c;无疑成为了技术革新的璀璨亮点。这一设计巧妙地将吸烟的声效融入使用体验中&#xff0c;使得用户在吸电子烟时…

CSS3 立体 3D 变换

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 ✍CSS3 立体 3D 变换&#x1f48e;1 坐标轴&#x1f48e;2 perspective 透视视…