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);
}
?>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器人瓶胚检测工作站(H3U脉冲轴控制)

1、变量定义 2、程序监控1 2、 程序监控2 3、程序监控3 机器人输送料和机构的动作安全尤为重要&#xff0c;下面我们讨论下安全联锁控制逻辑 4、相机拍照触发信号 5、相机拍照触发时序

Harmony鸿蒙南向外设驱动开发-LCD

功能简介 LCD&#xff08;Liquid Crystal Display&#xff09;驱动编程&#xff0c;通过对显示器上电、初始化显示器驱动IC&#xff08;Integrated Circuit&#xff09;内部寄存器等操作&#xff0c;使其可以正常工作。 基于HDF&#xff08;Hardware Driver Foundation&#…

Axure学习:网站后台导航菜单的制作及对应内容的显示

​不少产品经理主要做的产品是后台系统&#xff0c;在做后台原型的时候对于有些部分的内容存在一些疑惑。 我们的学员也是一样&#xff0c;在做后台的时候遇到了一些问题&#xff0c;请教了老师&#xff0c;得到了解答。这里和大家分享一下&#xff0c;同学们的问题以及解决方…

找到冠军 II

题目&#xff1a; 一场比赛中共有 n 支队伍&#xff0c;按从 0 到 n - 1 编号。每支队伍也是 有向无环图&#xff08;DAG&#xff09; 上的一个节点。 给你一个整数 n 和一个下标从 0 开始、长度为 m 的二维整数数组 edges 表示这个有向无环图&#xff0c;其中 edges[i] [u…

SpringBoot碎片化知识

参考资料&#xff1a; java官方词典&#xff1a;https://docs.oracle.com/javase/tutorial/information/glossary.html#F苍穹外卖&#xff1a;https://www.bilibili.com/video/BV1TP411v7v6 JavaBean规范 JavaBean规范是一种类的规范&#xff0c;其要求符合下列条件&#xf…

跟着教程使用腾讯云服务器一步步搭建网站教程,收藏级

使用腾讯云服务器搭建网站全流程&#xff0c;包括轻量应用服务器和云服务器CVM建站教程&#xff0c;轻量可以使用应用镜像一键建站&#xff0c;云服务器CVM可以通过安装宝塔面板的方式来搭建网站&#xff0c;腾讯云服务器网txyfwq.com整理使用腾讯云服务器建站教程&#xff0c;…

【vue】v-model.lazy等(非实时渲染)

v-model&#xff1a;实时渲染v-model.lazy&#xff1a;失去焦点/按回车后&#xff0c;才渲染v-model.number&#xff1a;值转换为数字v-model.trim&#xff1a;去除首尾空格 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8&qu…

「JavaEE」初识进程

初识进程 &#x1f349;进程&#x1f34c;操作系统的进程管理 &#x1f349;PCB 重要属性&#x1f34c;进程的身份标识&#x1f34c;内存指针&#x1f34c;文件描述符表&#x1f34c;进程的状态&#x1f34c;优先级&#x1f34c;记账信息&#x1f34c;上下文 &#x1f349;内存…

LongAdder和AtomicLong的对比实验

LongAdder 的核心思想是热点分离&#xff0c;与 ConcurrentHashMap 的设计思想类似&#xff1a;将value值分离成一个数组&#xff0c;当多线程访问时&#xff0c;通过Hash算法将线程映射到数组的一个元素进行操作&#xff1b;而获取最终的value结果时&#xff0c;则将数组的元素…

C++ 之 【类与对象】 从入门到精通一条龙服务 进阶篇(类的6个默认成员函数,构造,析构。。。)

以后把闹钟换成唢呐&#xff0c;醒了就起床&#xff0c;不醒就上天堂 一、类的6个默认成员函数 二、构造函数 1.概念 2.特性 三、析构函数 1.概念 2.特性 四、拷贝构造函数 1.概念 2.特征 五、赋值运算符重载 1.运算符重载 2.赋值运算符重载 3.前置和后置重载 六…

[大模型]Qwen1.5-7B-Chat FastApi 部署调用

Qwen1.5-7B-Chat FastApi 部署调用 环境准备 在 Autodl 平台中租赁一个 3090 等 24G 显存的显卡机器&#xff0c;如下图所示镜像选择 PyTorch–>2.0.0–>3.8(ubuntu20.04)–>11.8&#xff08;11.3 版本以上的都可以&#xff09;。 接下来打开刚刚租用服务器的 Jupyt…

pom.xml显示灰色并被划线

在使用 IDEA 进行开发的过程中&#xff0c;有时候会遇到 pom.xml 显示灰色并被划线的情况&#xff0c;如下图&#xff1a; 这一般是因为该文件被 Maven 忽略导致的&#xff0c;可以进行如下操作恢复&#xff1a; 设置保存后&#xff0c;可以看到 pom.xml 恢复了正常&#xff1a…

使用 Java 原生或 Hutool 工具包编写非对称加解密的工具类

1、什么是非对称加密 使用一对&#xff08;2个&#xff09;密钥&#xff1a;一个用于加密信息&#xff0c;另一个则用于解密信息。有“公钥&#xff08;Public Key&#xff09;”和“私钥&#xff08;Private Key&#xff09;”之分。 非对称加密的“公钥”和“私钥”是成对出现…

Java 中文官方教程 2022 版(四十九)

原文&#xff1a;docs.oracle.com/javase/tutorial/reallybigindex.html JAXB 示例 原文&#xff1a;docs.oracle.com/javase/tutorial/jaxb/intro/examples.html 以下部分描述如何使用包含在 JAXB RI 捆绑包中的示例应用程序。JAXB RI 捆绑包可从jaxb.java.net获取。下载并安装…

基于OptiTrack跟踪系统和Turtlebot机器人的视觉SLAM定位评估

本文旨在介绍使用OptiTrack光学跟踪系统和Turtlebot机器人进行视觉SLAM定位实验的详细流程&#xff0c;包括实验平台搭建过程、数据处理过程以及SLAM估计评估方法。由于涉及知识较多&#xff0c;部分内容只给出了相关参考博文链接。 1 实验平台搭建 实验平台包括OptiTrack光学…

使用 Meltano 将数据从 Snowflake 导入到 Elasticsearch:开发者之旅

作者&#xff1a;来自 Elastic Dmitrii Burlutskii 在 Elastic 的搜索团队中&#xff0c;我们一直在探索不同的 ETL 工具以及如何利用它们将数据传输到 Elasticsearch&#xff0c;并在传输的数据上实现 AI 助力搜索。今天&#xff0c;我想与大家分享我们与 Meltano 生态系统以及…

Python项目1 外星人入侵_记分

在本章中&#xff0c;我们将结束游戏《外星人入侵》的开发。我们将添加一个Play按钮&#xff0c;用于根据需要启动游戏以及在游戏结束后重启游戏。我们还将修改这个游戏&#xff0c;使其在玩 家的等级提高时加快节奏&#xff0c;并实现一个记分系统。阅读本章后&#xff0c;你将…

2024年【山东省安全员C证】考试资料及山东省安全员C证考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 山东省安全员C证考试资料考前必练&#xff01;安全生产模拟考试一点通每个月更新山东省安全员C证考试试题题目及答案&#xff01;多做几遍&#xff0c;其实通过山东省安全员C证作业模拟考试很简单。 1、【多选题】.设…

【计算机毕业设计】人事管理系统——后附源码

&#x1f389;**欢迎来到我的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 一名来自世界500强的资深程序媛&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 在深度学习任务中展现出卓越的能力&#xff0c;包括但不限于…

二叉搜索树--搜索二维矩阵 II

题目描述 编写一个高效的算法来搜索 m * n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,…