Latest version of php compressed folder

  • 2021-10-24 19:16:16
  • OfStack

This article example for everyone to share the php compressed folder specific code, for your reference, the specific content is as follows

Advantages:

1. Supports compressing Chinese file names
2. Support subdirectory recursive compression
3. With zip files, repeated compression will merge new files, overwrite the intersection part of the original zip, do not delete the files that disappear in the directory, but only increase or decrease (create a directory by yourself, generate test. zip with only A and B files, then add C files in the directory, and then compress them into test. zip with the same name, then there will be ABC 3 files in zip; If you delete other files from the directory and keep only the A file, the generated test. zip will not change, but there is still ABC in it.)

Disadvantages:

1. Single file cannot be compressed (todo)
2. Under the folder, you can't just select a few files for compression (todo)


/**
 *  General interface 
 * @param $dir_path  Directory address to be compressed (absolute path) 
 * @param $zipName  What needs to be generated zip File name (absolute path) 
 */
function zip($dir_path,$zipName){
  $relationArr = [$dir_path=>[
    'originName'=>$dir_path,
    'is_dir' => true,
    'children'=>[]
  ]];
  modifiyFileName($dir_path,$relationArr[$dir_path]['children']);
  $zip = new ZipArchive();
  $zip->open($zipName,ZipArchive::CREATE);
  zipDir(array_keys($relationArr)[0],'',$zip,array_values($relationArr)[0]['children']);
  $zip->close();
  restoreFileName(array_keys($relationArr)[0],array_values($relationArr)[0]['children']);
}

/**
 *  Recursively add files into zip
 * @param $real_path  In the local directory that needs to be compressed 
 * @param $zip_path zip Relative directory inside 
 * @param $zip ZipArchive Object 
 * @param $relationArr  Naming relationship of directories 
 */
function zipDir($real_path,$zip_path,&$zip,$relationArr){
  $sub_zip_path = empty($zip_path)?'':$zip_path.'\\';
  if (is_dir($real_path)){
    foreach($relationArr as $k=>$v){
      if($v['is_dir']){ // Is a folder 
        $zip->addEmptyDir($sub_zip_path.$v['originName']);
        zipDir($real_path.'\\'.$k,$sub_zip_path.$v['originName'],$zip,$v['children']);
      }else{ // Not a folder 
        $zip->addFile($real_path.'\\'.$k,$sub_zip_path.$k);
        $zip->deleteName($sub_zip_path.$v['originName']);
        $zip->renameName($sub_zip_path.$k,$sub_zip_path.$v['originName']);
      }
    }
  }
}

/**
 *  Recursively change the file name of the directory to random non-duplicate number, and then save the original name and numbering relationship 
 * @param $path  Local directory address 
 * @param $relationArr  Relational array 
 * @return bool
 */
function modifiyFileName($path,&$relationArr){
  if(!is_dir($path) || !is_array($relationArr)){
    return false;
  }
  if($dh = opendir($path)){
    $count = 0;
    while (($file = readdir($dh)) !== false){
      if(in_array($file,['.','..',null])) continue; // Invalid file, restart 
      if(is_dir($path.'\\'.$file)){
        $newName = md5(rand(0,99999).rand(0,99999).rand(0,99999).microtime().'dir'.$count);
        $relationArr[$newName] = [
          'originName' => iconv('GBK','UTF-8',$file),
          'is_dir' => true,
          'children' => []
        ];
        rename($path.'\\'.$file, $path.'\\'.$newName);
        modifiyFileName($path.'\\'.$newName,$relationArr[$newName]['children']);
        $count++;
      }
      else{
        $extension = strchr($file,'.');
        $newName = md5(rand(0,99999).rand(0,99999).rand(0,99999).microtime().'file'.$count);
        $relationArr[$newName.$extension] = [
          'originName' => iconv('GBK','UTF-8',$file),
          'is_dir' => false,
          'children' => []
        ];
        rename($path.'\\'.$file, $path.'\\'.$newName.$extension);
        $count++;
      }
    }
  }
}

/**
 *  Restore the file name of the local directory to the original file name according to the relational array 
 * @param $path  Local directory address 
 * @param $relationArr  Relational array 
 */
function restoreFileName($path,$relationArr){
  foreach($relationArr as $k=>$v){
    if(!empty($v['children'])){
      restoreFileName($path.'\\'.$k,$v['children']);
      rename($path.'\\'.$k,iconv('UTF-8','GBK',$path.'\\'.$v['originName']));
    }else{
      rename($path.'\\'.$k,iconv('UTF-8','GBK',$path.'\\'.$v['originName']));
    }
  }
}

Related articles: