PHP traverses folders and compresses downloads according to filtering results

Requirements: Files and folders under the specified path are filtered out and packaged for download.

Note: The mvc structure of php can be downloaded by adding header header to the controller, but this method can not be used if the front-end Ajax request interface is used, because both json data and binary files are treated as strings by browsers.

1. Controller interface for Ajax calls

public function download(){  
      $source_file_path = "./upload/".$uuid;  //The folder address to traverse
      if(!is_dir($source_file_path)){  //Check if the directory exists
            return;
      }
      $des_file_path = storage_path("zip/".$uuid.".zip"); //Purpose Path

      if(file_exists($des_file_path)){  //Reproduction of files
           unlink($des_file_path);
      }
      $zip=new \ZipArchive();
      if($zip->open($des_file_path, \ZipArchive::OVERWRITE)=== TRUE){
           $this->addFileToZip($source_file_path, $zip); //Call methods, manipulate the root directory to be packaged, and pass ZipArchive objects to methods
           $zip->close(); //Close the processed zip file
           if(!file_exists($des_file_path)){
                return response()->json(['status' => '404','msg'=>'No eligible files were queried']);
                //exit('unable to find files'); and // even if created, it is still possible to fail, for example, if there is no qualified file, there is no addfile
                }

//If it's not an Ajax request, you can download it directly from the annotated header
//                header("Cache-Control: public");
//                header("Content-Description: File Transfer");
//                Header ("Content-Type: application/zip"); in //zip format
//                header("Content-Transfer-Encoding: Binary"); tell the browser that this is a binary file
//                Header ('Content-Disposition: attachment; filename='. basename ($des_file_path); // filename

//                Header ('Content-Length:'. filesize ($des_file_path); // Tell the browser the size of the file
//                @readfile($des_file_path);
//                unlink($des_file_path); //// Delete compressed packages
//                exit;
        }else{
             exit('Unable to open the file, or file creation failed');
        }
       
        $download_file_path = "/Project/storage/zip/".$finally_uuid.".zip";//File path dropped by js
        return response()->json(['url' => $download_file_path],200,[],JSON_UNESCAPED_SLASHES);
}

2. The addFileToZip method (traversing folders) used by the controller can be written into the helper function.

public function addFileToZip($path,$zip){
        //Define an array that prints debugging and lists all eligible files
        //$files = array();

        $handler=opendir($path); //Opening the current folder is specified by $path.
        while(($file = readdir($handler)) !== false){
            if($file != "." && $file != ".."){ //Folder files are named'. 'and'.'. Do not operate on them.
                if(is_dir($path."/".$file)){ // If an object read is a folder, then recursion
                    $this->addFileToZip($path."/".$file, $zip);
                }else{ //Add files to zip objects
                 //Here else writes the conditional code that you want to filter files, such as doing something based on the timestamp, filectime 
//                        $files[] = $path . "/" . $file; 
                        $zip->addFile($path."/".$file,$file);  //Add the traversed file to the zip to be compressed, and the second parameter specifies the local_name of the folder where the file is located (if the file itself is a zip package, zip suffix is needed for compression)

//                    $path_arr = explode("/",$path);
//                    $prefix_file = $path_arr[count($path_arr)-1];
//                    $zip - > renameName ($path. "/". $filename, $prefix_file.'/'. $file); //$prefix_file is the name of the folder where the compressed file is located, if not, indicating that all files are of the same class, renameName is the second parameter of the addFile method. If your path folder is the last level (that is, all files in the directory, no directory), ignore the prefix $prefix_file
                }
            }
        }
        @closedir($path);
    }

3. Front-end call interface

$.ajax({
       type:"POST",
       url:"download",//Your routing address
       dataType:"json",
       async: false,
       data:JSON.stringify({"uuid":123456789}),
       success:function (result) {
               if("404"==result.status){
                    alert(result.msg);
               else{
                    window.open("" +result.url);
//                  window.location.href=result.url
               }
       }
})

Note: Why can't js Download with header? Look here. The situation is not different from what he described.

Keywords: JSON PHP encoding

Added by mattotto77 on Tue, 30 Jul 2019 22:45:42 +0300