PHP Download Script Creates Unreadable ZIP File on Mac

前端 未结 3 576
青春惊慌失措
青春惊慌失措 2021-01-07 13:53

For reference, I have already read and tried the answers in these and several other threads:

Creating and serving zipped files with php

Opening downloaded zi

相关标签:
3条回答
  • 2021-01-07 14:06

    Here is what works

    $zipName = 'myfile.zip';
    $zipPath = 'mydirectory/' . $zipName;
    
        if (file_exists($zipPath)) {
    
            header("Pragma: public");
            header("Expires: 0");
            header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
            header("Cache-Control: public");
            header("Content-Description: File Transfer");
            header("Content-type: application/octet-stream");
            header("Content-Disposition: attachment; filename=\"".$zipName."\"");
            header("Content-Transfer-Encoding: binary");
            header("Content-Length: ".filesize($zipPath));
            ob_end_flush();
            @readfile($zipPath);
    }
    
    0 讨论(0)
  • 2021-01-07 14:11

    Often the issue is caused by extra characters that have been printed or echo'd to the page before you read out the file. Even a space will cause the failure. To fix that issue, call ob_end_clean(); before you read the file which will clear the output buffer and turn off buffering.

    But keep in mind you can have nested output buffers, and this will corrupt your download as well (cheers to Vladamir for figuring this out). So to clear the output buffer completely run this before you read your file:

    while (ob_get_level()) {
        ob_end_clean();
    }    
    

    This will clear out your entire buffer and you won't have any extra characters to mess up your download.

    For those interested i've pasted my download script below. My zip files now download perfectly, and so far this works great.

    if (file_exists($zip_file_path)) {
    
            header("Pragma: public");
            header("Expires: 0");
            header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
            header("Cache-Control: public");
            header("Content-Description: File Transfer");
            //We can likely use the 'application/zip' type, but the octet-stream 'catch all' works just fine.  
            header("Content-type: application/octet-stream");
            header("Content-Disposition: attachment; filename='$zip_file_name'");
            header("Content-Transfer-Encoding: binary");
            header("Content-Length: ".filesize($zip_file_path));
    
            while (ob_get_level()) {
                 ob_end_clean();
            }
    
            @readfile($zip_file_path);
    
            exit;
    }
    
    0 讨论(0)
  • 2021-01-07 14:25

    Well, I presume you know that your $fsize variable is not being written to that header because it's enclosed by quotes. You could try something like this:

    header('Cache-Control: public');
    header('Content-Description: File Transfer');
    header('Content-Disposition: attachment; filename=\"".$zipname."\"');
    header('Content-Type: application/zip');
    
    0 讨论(0)
提交回复
热议问题