zip递归压缩文件夹,递归的时候,后续逻辑被忽略,导致文件丢失

问题说明
  • 代码目的
    • 这是一段用来压缩 指定文件夹 的代码,原意是想通过递归压缩 指定文件夹下的所有的文件并且保留原本目录结构
  • 问题
    • 用scandir()方法扫描文件夹目录,如果扫描出来的目录顺序是,文件1->文件夹->文件2,那文件2在递归的时候,会被忽略掉
  • 压缩文件结果示例
    压缩结果
  • 代码疑惑片段
    代码疑惑部分
  • 想要的结果
    • 想明白为什么递归会导致后面的逻辑被忽略
    • 这段代码能在优化嘛
    • 在此先谢过各位大佬了
      代码
      /**
      * 压缩文件夹
      * @param string $aim_dir   想要压缩哪个文件夹
      * @param string $zip_name  压缩包的名称,不用带后缀
      * @param string $son_dir_path  用来记录子目录的完整路径,递归使用,不需要传递
      * @param string $zip_storage_path  用来记录zip储存路径,递归使用,不需要传递
      * @param ZipArchive $zipArchiveClass  用来传递zip对象,递归使用,不需要传递
      * @return string
      */
      function zipDir(string $aim_dir,string $zip_name,string $son_dir_path = '',string $zip_storage_path = '', $zipArchiveClass = ''):string{
        $zip_full_name = $zip_name.'.zip';
        //初始化zip最终储存目录
        if($zip_storage_path == ''){
            $zip_storage_path = $aim_dir.DIRECTORY_SEPARATOR.$zip_full_name;
        }
        //初始化ZipArchive类
        if($zipArchiveClass == ''){
            $zipArchiveClass = new ZipArchive();
            $zipArchiveClass->open($zip_storage_path, ZipArchive::CREATE | ZipArchive::OVERWRITE);
        }
        //扫描目录添加文件
        foreach (scandir($aim_dir) as $dpv){
            if(in_array($dpv,['.','..'])){
                continue;
            }
            $file_path = $aim_dir.DIRECTORY_SEPARATOR.$dpv;
            //如果是文件夹就递归处理
            if(is_dir($file_path)){
                //用来标记文件目录,虽然和下面$entry_name中的逻辑一样,但是不能向上提取出来变为一句,别问怎么知道的
                $son_dir_path = $son_dir_path == '' ? $dpv : $son_dir_path.DIRECTORY_SEPARATOR.$dpv;
                zipDir($file_path, $zip_name,$son_dir_path,$zip_storage_path,$zipArchiveClass);
            }else{
                //获取子文件下文件完整路径,不加这段逻辑不能完整的保留目标文件夹下的目录结构,所有文件都会被提取压缩包的根目录
                $entry_name = $son_dir_path == '' ? $dpv : $son_dir_path.DIRECTORY_SEPARATOR.$dpv;
                $zipArchiveClass->addFile($file_path,$entry_name);
            }
        }
        $zipArchiveClass->close();
        return $zip_full_name;
      }
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 6
mouyong

github.com/mouyong/php-support/blo...

(new Zip)->pack($dir, 'filename.zip', storage_path());

2年前 评论
simpleId (楼主) 2年前
mouyong (作者) 2年前
simpleId (楼主) 2年前

拿你的代码小改了一下

/**
* 压缩文件夹
* @param string $aim_dir   想要压缩哪个文件夹
* @param string $zip_name  压缩包的名称,不用带后缀
* @param string $son_dir_path  用来记录子目录的完整路径,递归使用,不需要传递
* @param string $zip_storage_path  用来记录zip储存路径,递归使用,不需要传递
* @param ZipArchive $zipArchiveClass  用来传递zip对象,递归使用,不需要传递
* @return string
*/
function zipDir(string $aim_dir,string $zip_name,string $son_dir_path = '',string $zip_storage_path = '', $zipArchiveClass = ''):string{
  $zip_full_name = $zip_name.'.zip';
  //初始化zip最终储存目录
  if($zip_storage_path == ''){
      $zip_storage_path = $aim_dir.DIRECTORY_SEPARATOR.$zip_full_name;
  }
  //初始化ZipArchive类
  if($zipArchiveClass == ''){
      $zipArchiveClass = new ZipArchive();
      $zipArchiveClass->open($zip_storage_path, ZipArchive::CREATE | ZipArchive::OVERWRITE);
  }
  //扫描目录添加文件
$handle = opendir($aim_dir);
if (!$handle) return false;
 // 循环读取文件夹内容
while (false !== ($file = readdir($handle))) {
   //过滤掉Linux系统下的.和..文件夹
   if ($file != '.' && $file != '..') {
       // 文件指针当前位置指向的如果是文件夹,就递归压缩
      if (is_dir($path . '/' . $file)) {
         zipDir($aim_dir. '/' . $file, $zip_name, $file, $zip);
      } else {
             $zipArchiveClass ->addFile($path . '/' . $file, $zip_storage_path . '/' . $file);
      }
  }
}
   @closedir($handle);
  $zipArchiveClass->close();
  return $zip_full_name;
}
2年前 评论
simpleId (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!