Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zipped file with PHP results in cpgz file after extraction

Tags:

php

zip

I'm zipping folders and files with php, but when I try to open up the zip file I get an cpgz file instead. After extracting that file I get another zip file. What it does is bassicaly scan the current folder for files and folders to zip. This is the code I use:

function Zip($source, $destination)
{
if (!extension_loaded('zip') || !file_exists($source)) {
    return false;
}

$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
    return false;
}

$source = str_replace('\\', '/', realpath($source));

if (is_dir($source) === true)
{
    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

    foreach ($files as $file)
    {
        $file = str_replace('\\', '/', realpath($file));

        if (is_dir($file) === true)
        {
            $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
        }
        else if (is_file($file) === true)
        {
            $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
        }
    }
}
else if (is_file($source) === true)
{
    $zip->addFromString(basename($source), file_get_contents($source));
}

return $zip->close();
}


if($_GET["archive"]== 'true'){
$date = date("Ymd_Hi");
$dir = dirname(__FILE__);
$filename = $date.".zip";

Zip(getcwd(), $filename);

header("Content-disposition: attachment; filename=$filename");
header('Content-type: application/zip');
readfile($filename);
unlink($filename);
}
like image 230
Steven Dobbelaere Avatar asked Jul 12 '12 14:07

Steven Dobbelaere


1 Answers

I was just having exactly the same issue, and learned that these two function calls can help:

header("Content-disposition: attachment; filename=$filename");
header('Content-type: application/zip');

// Add these
ob_clean();
flush();

readfile($filename);
unlink($filename);

Usually setting Content-Disposition and Content-Length should be enough, however flushing PHPs output buffer and the underlying output buffer (Apache or such) helps when output is accidentally sent before headers are set in PHP.

In my case, commenting out the header() and readfile() calls for debugging helped to see, that warnings were output before the file was sent.

Hope that helps somebody in the future.

like image 133
martinczerwi Avatar answered Sep 20 '22 17:09

martinczerwi