Home » Php » php – ZIP all files in directory and download generated .zip

php – ZIP all files in directory and download generated .zip

Posted by: admin April 23, 2020 Leave a comment

Questions:

Well, first of all, this is my folder structure:

images/

image1.png
image11.png
image111.png
image223.png
generate_zip.php

And this is mine generate_zip.php:

<?php

    $files = array($listfiles);

    $zipname = 'adcs.zip';
    $zip = new ZipArchive;
    $zip->open($zipname, ZipArchive::CREATE);
    foreach ($files as $file) {
      $zip->addFile($file);
    }
    $zip->close();

    header('Content-Type: application/zip');
    header("Content-Disposition: attachment; filename='adcs.zip'");
    header('Content-Length: ' . filesize($zipname));
    header("Location: adcs.zip");

    ?>

How to gather all the files from “images/” folder, except “generate_zip.php”, and make it a downloadable .zip? In this case the “images/” folder always have a different image. Is that possible?

How to&Answers:

this will ensure a file with .php extension will not be added:

   foreach ($files as $file) {
        if(!strstr($file,'.php')) $zip->addFile($file);
    }

edit: here’s the full code rewritten:

<?php

    $zipname = 'adcs.zip';
    $zip = new ZipArchive;
    $zip->open($zipname, ZipArchive::CREATE);
    if ($handle = opendir('.')) {
      while (false !== ($entry = readdir($handle))) {
        if ($entry != "." && $entry != ".." && !strstr($entry,'.php')) {
            $zip->addFile($entry);
        }
      }
      closedir($handle);
    }

    $zip->close();

    header('Content-Type: application/zip');
    header("Content-Disposition: attachment; filename='adcs.zip'");
    header('Content-Length: ' . filesize($zipname));
    header("Location: adcs.zip");

    ?>

Answer:

======= Working solution !======

includes all sub-folders:

new GoodZipArchive('path/to/input/folder',    'path/to/output_zip_file.zip') ;

at first, include this piece of code.

Answer:

Since you just need specific files from a directory to create ZipArchive you can use glob() function to do this.

<?php
    $zip = new ZipArchive;
    $download = 'download.zip';
    $zip->open($download, ZipArchive::CREATE);
    foreach (glob("images/*.png") as $file) { /* Add appropriate path to read content of zip */
        $zip->addFile($file);
    }
    $zip->close();
    header('Content-Type: application/zip');
    header("Content-Disposition: attachment; filename = $download");
    header('Content-Length: ' . filesize($download));
    header("Location: $download");
 ?>

Don’t use glob() if you try to list files in a directory where very much files are stored (more than 100.000). You get an “Allowed memory size of XYZ bytes exhausted …” error.

readdir() is more stable way.

Answer:

change your foreach loop to this to except generate_zip.php

 foreach ($files as $file) {
     if($file != "generate_zip.php"){
        $zip->addFile($file);
     }
 }

Answer:

<?php 
ob_start();
$zip = new ZipArchive; 
$zip->open('sample.zip',  ZipArchive::CREATE);
$srcDir = "C:\xampp\htdocs\uploads"; //location of the directory
$files= scandir($srcDir);
print_r($files);  // to check if files are actually coming in the array

unset($files[0],$files[1]);
foreach ($files as $file) {
    $zip->addFile($srcDir.'\'.$file, $file);
    echo "bhandari";
}
$zip->close();

$file='sample.zip';
if (headers_sent()) {
    echo 'HTTP header already sent';
} else {
    if (!is_file($file)) {
        header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
        echo 'File not found';
    } else if (!is_readable($file)) {
        header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
        echo 'File not readable';
    } else {
        header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
        header("Content-Type: application/zip");
        header("Content-Transfer-Encoding: Binary");
        header("Content-Length: ".filesize($file));
        header("Content-Disposition: attachment; filename=\"".basename($file)."\"");
        while (ob_get_level()) {
            ob_end_clean();
          }
        readfile($file);
        exit;
    }
}



?>`enter code here`

Note: Don’t forget to use ob_start(); and end .

Answer:

I went with way2vin’s solution. However I had to replace

$zip->addFile(“{$file}”);

with

$zip->addFromString(basename($file), file_get_contents($file));

which did the trick. Found this here: Creating .zip file