3

I used to be able to create dynamic zip files just fine with this:

if(isset($_POST['files'])) {
    $zip = new ZipArchive();
    $zip_name = $_POST['name'].".zip";
    if($zip->open($zip_name, ZIPARCHIVE::CREATE)===TRUE) { 
        foreach($_POST['files'] as $file){
            //here $file is like 'path/to/file.pdf' with no special characters in the name
            $name = basename($file);
            if(file_exists($file)){
                $zip->addFile($file, $name);
            }
        }
        $zip->close();
        if(file_exists($zip_name)) {
            header('Content-type: application/zip');
            header('Content-Disposition: attachment; filename="'.$zip_name.'"');
            readfile($zip_name);
            unlink($zip_name);
        }
    }
}

But now it creates invalid zip files. In windows you get an error message, on mac you get a never ending zip file loop. I've tried a lot of different suggestions on other questions (including the addFromSting method) but I haven't found a solution.

Thank-you

justin
  • 43
  • 1
  • 6
  • This used to work? Never changed anything? I'm curious on `foreach($_POST['files'] as $file)` and `if(file_exists($file))` ... could you include how this script is begun? The form used, for example. Also, have you tested with files that used to work, and do they still work, or do they now fail? – IncredibleHat Jan 17 '18 at 18:08
  • @IncredibleHat Nope, nothing changed. Client said this morning that it stopped working. This is the beginning of the file, when a button on the page is clicked a form with hidden inputs valued with the file paths is sent to the page. I tested on pages that used to work, as well as creating a static array of file paths to use instead but it still fails – justin Jan 17 '18 at 19:10

1 Answers1

0

I added clearstatcache(); to help, as well as header('Content-Length: ' . filesize($zip_name)); to double check and the produced zip file always seemed to be a proper size, no matter what files were included

I ended up trying a few more things until I stumbled upon a clue. The file_exists() in the foreach was false, always. At launch it would look relative to the domain, but somewhere along the lines it started to look relative to where the script was located. So I added a little catch for it and it started working

if(file_exists($file)){
    $zip->addFile($file, $name);
} else if(file_exists('../../../'.$file)){
    $zip->addFile('../../../'.$file, $name);
}

still no idea why the filesize() would work though

justin
  • 43
  • 1
  • 6