Search code examples
phpdownloadreadfilephp-ziparchive

prevent zip archive download twice in two different folder


I tried to create a zip file using zip archive, it works fine although the zip file is downloaded twice in two different folders at same time, the htdocs folder where the source code is and the default download folder from browser setting. Is there any way that I could prevent this? I only want it to be downloaded once into download folder...

   $file_names = explode(',', $_REQUEST['files']);

   $dir = $_REQUEST['currentdir'];

   //Archive name
   $archive_file_name="Downloaded_".date("Y-m-d_G-i-s").".zip"; 

   //Download Files path
   $file_path=$dir;

   //cal the function
   zipFilesAndDownload($file_names,$archive_file_name,$file_path);

   function zipFilesAndDownload($file_names,$archive_file_name,$file_path)
   {
   $zip = new ZipArchive();
   $res = $zip->open($archive_file_name, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE );
if ($res===TRUE) {
//add each files of $file_name array to archive
foreach($file_names as $files)
{
    $tt=$file_path."/".$files;
    if (file_exists($tt)){
    $zip->addFile($tt,$files);
    }
    else{
        return false;
        exit;
    }
}
$zip->close();

//then send the headers to force download the zip file
header('Content-type: application/zip'); 
header("Content-Disposition: attachment; filename=\"".basename($archive_file_name)."\""); 
header('Pragma: no-cache'); 
header('Expires: 0'); 
//header('Content-Length: ' . filesize($archive_file_name));
ob_end_clean();
//flush();
readfile($archive_file_name);
exit; 
}
else{
    return false;
    exit;
}

}

Solution

  • Your PHP script creates the zip in the local directory, which is your htdocs directory.

    You have a few options now:

    • Delete the zip archive after reading the archive with php (readfile)
    • Create the zip archive in a subdirectory, if you need to save it for later (archiving)
    • Create the zip in the temporary folder and delete the zip after use

    I would go with option 3, as it will ensure that the zip gets ever deleted if the script dies before being able to delete it.

    You can delete a file with the unlink() command. You just pass the filename or filepath to it and it does it (if the file exists). If you want to save it in a subdirectory, you just prepend the directory name with the directory separator to the filename. If you want to save it e.g. in the subdirectory 'downloads', you just add downloads/ before the filename. $archive_file_name="downloads/Downloaded_".date("Y-m-d_G-i-s").".zip";

    The better option here is to create the zip in the server's temporary directory and manually delete it, so the zip gets cleaned up as soon as it's done. You will get the server's temporary directory with sys_get_temp_dir(), which you can prepend to the filename. After you're done with your business you can just delete the file with unlink(). $archive_file_name=sys_get_temp_dir()."Downloaded_".date("Y-m-d_G-i-s").".zip";

    After you're done and want to delete the file you just do unlink($archive_file_name);.

    Function reference:

    http://php.net/unlink

    http://php.net/sys_get_temp_dir