Tony Xu
Tony Xu

Reputation: 3091

Why zip file can't be opened after downloaded but fine via manual transfer?

I searched and tried a few previous questions/example codes, but couldn't get this to work.

I'm trying to deliver the results to end-users via PHP code. Here is my code.

       $varZipFile = $varBaseNameParts[0] . '.' . $varDate . '.zip';
       $varZipDir = $varBaseNameParts[0] . '_' . $varDate;

       $zip = new ZipArchive();
       $zip->open($varZipFile, ZipArchive::CREATE | ZipArchive::OVERWRITE);
       $zip->addFile('008.csv');
       $zip->addFile('002.csv');
       $zip->close(); // mark line xxx

       header("Content-Type: application/zip");
       header("Content-disposition: attachment;filename=$varZipFile");
       header('Content-Length: ' . filesize($varZipFile)); // with or without this line, got the same error 
       header("Content-Type: application/force-download"); // with or without this line, got the same error 
       readfile($varZipFile);

I got the .zip file in my browser. However WinZip cannot open it, neither can 7-Zip. WinZip complains that "Error: Central directory not found".

Interestingly, when I manually transfer the file via WinSCP from my server to my Windows machine, I can open the file with either WinZip or 7-Zip. This indicates it works all fine to 'mark line xxx', and problems occurs in the header lines.

TIA!

Upvotes: 0

Views: 2300

Answers (2)

coderodour
coderodour

Reputation: 1057

Your ouput buffer may not be cleared before you try to serve the download. Try to clean the output buffer before serving the download with the ob_clean() function like this:

$zip->close(); // mark line xxx
ob_clean();

Upvotes: 3

Junius L
Junius L

Reputation: 16132

Your code is working well on my side, debug this $varBaseNameParts[0] to see if the value is correct or try the below code.

// $name = name of the archive
// $archive_directory = directory to save the archive
// $file_array = list of files
function create_archive($name, $archive_directory, $file_array) {
    $target_file = $archive_directory . '/' . $name . date('m-d-y').date('h-i-sa') . '.zip';
    $zip = new ZipArchive();
    if (count($file_array)) {
        if ($zip->open($target_file, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)) {
            foreach ($file_array as $file) {
                $zip->addFile($file);
            }
            $zip->close();
            chmod($target_file, 0777);
            return $target_file;
        }
    }
    return null;
}

function create_download($archive) {
    $file_name = basename($archive);
    header("Content-Type: application/zip");
    header("Content-Disposition: attachment; filename=$file_name");
    header("Content-Length: " . filesize($archive));

    readfile($archive);
}

// create the archive file
$archive = create_archive('test', 'archive', ['008.csv', '002.csv']);
if ($archive) {
    create_download($archive);
}

Upvotes: 0

Related Questions