Search code examples
phpcakephpphp-ziparchive

Zip PDF-Files download not working


I'm building an interface that allows collecting PDF-Files from a server-path to download them zipped at once which works fine most of the time. Now, some PDF-Files are not working, means if the zip contains one of the non-working files the whole download will not performed.

Now i tried many files with different sizes. I can tell most of the files larger than 10MB are not working, but one file (15mb) is working, so it can't be the file-size causing this error - right?

What happens is there's just no download at all. Additionally tried reading the results of "$zip->addFile" and "$zip->close" but it's all true, even if the download will not be performed. ANY ideas which may cause this bug or at least some hints on how to find this out?

The (x)debug inspection of the variables during process does not differ between the time it worked and the time its not working. Only differences are filesizes and -paths.

Here's the Code i'm using to build the ZIP:

public function downloadFiles() {
        $myFiles = $this->Session->read('Files.MyFiles');
        if(count($myFiles)) {
            // build zip
            $zipname = 'amaz_photos_' . time() . '.zip';
            $zip = new ZipArchive();
            $zip->open($zipname, ZipArchive::CREATE);
            foreach($myFiles as $file) {
                if($file['type'] == 'directory') {
                    $dirName = str_replace('/', '', substr($file['path'], strrpos($file['path'], '/'), (strlen($file['path']) - strrpos($file['path'], '/'))));
                    $zip->addEmptyDir($dirName);
                    $this->addFolderToZip($file['path'] . '/', $zip, $dirName . '/');
                } else {
                    $zip->addFile($file['path'], str_replace('/', '', substr($file['path'], strrpos($file['path'], '/'), (strlen($file['path']) - strrpos($file['path'], '/')))));
                }
            }
            $zip->close();
            // get(send) zip
            header('Content-Type: application/zip');
            header('Content-disposition: attachment; filename=' . $zipname);
            header('Content-Length: ' . filesize($zipname));
            readfile($zipname);
            ignore_user_abort(true);
            unlink($zipname);
        }

        // clear "myFiles"
        //$this->Session->write('Files.MyFiles', array());

        $this->redirect(array(
            'controller' => 'pages',
            'action' => 'display'
        ));
    }

After all i tried opening the affected files with several PDF-Readers including Adobe's original to determine if its broken, but ̶i̶̶t̶̶s̶ it seems not.

This will occur in openable zip-files but the download does not start anyways. I found out that in that special cases where the download does not start, there is no response-header ("application/zip") being set on the network-frame compared to the times it worked.

What I found out else: Lets say I have a folder with 20 files in it, that's not downloading. I tried selecting file 1-10: downloading, then I tried downloading file 11-20: downloading, then I tried to download file 1-20: not downloading, then I tried two times mixing the patterns, first the even files 2,4,6,8.. (1-20), after that the odd files 1,3,5,7,.. (1-20): each not downloading. This states out the error does not belong to a specific file.

Any suggestions how to determine the trigger for this error?


Update:

I was able to download the generated zip-file doing these steps:

  1. Trigger 'create & download zip-file'

  2. It creates a zip-file but not download it

  3. Type the generated zip-files filename in the code to download it on the next procedure (e. g. "$zipname = "generatedOnStep1.zip").

  4. Trigger 'create & download zip-file' again

  5. It does not download the (recently) generated file, but the file i generated in step 1. So it seems that: Generating Zip-Files is working AND downloading that same zip-File is working, but not at once and only in some unknown combinations.

...

Update 2:

Since I was not able to determine the issue nor fix it, I ended up redesigning the whole process, to redirect to the generated zip-file instead of "readfile" it. Some features had to be sourced out but anyways it works this way.


Solution

  • Try this... Remove readfile($zipname); and replace it with these:

    /* make sure no other functions
    holding this file */
    $filehandle = fopen($zipname, "r");
    
    while (!feof($filehandle)) {
      /* lets read the file by pieces and
      send it to user's browser */
      echo fread($filehandle, 8192);
    }
    
    fclose($filehandle);
    

    Hope this helps.