Search code examples
phpmysqlhttpzipphp-ziparchive

ZIP file download php readfile() error


I know this question is posted in this forum for many times, but trust me I have tried all the possible solutions suggested but it didn't work for me.

I am trying to download multiple files using zip, though the zip file gets downloaded successfully, its corrupt and I encounter error after opening it in notepad:

Warning: readfile(E:\Downloads/IMG-20140831-WA0000.zip) [function.readfile]: failed to open stream: No such file or directory in...

I tried all the possible solutions mentioned in the forum such as header-check, web server user has write permission to the folder where I am creating the ZIP file, error-checking before downloading etc. but it did't worked out.

After performing error checking, I encountered something like

Error creating ZIP file : IMG-20140831-WA0000.zip

My code snippet:

function zipFilesDownload($file_names, $archive_file_name, $file_path) {
    $zip = new ZipArchive;
    if ($zip->open($archive_file_name, ZipArchive::CREATE) !== TRUE) {
        exit("cannot open <$archive_file_name>\n");
    }
    foreach($file_names as $files) {
        $zip->addFile($file_path . $files, $files);
    }
    if ($zip->close() === false) {
        exit("Error creating ZIP file : " . $archive_file_name);
    }
    if (file_exists($archive_file_name)) {
        header("Content-Description: File Transfer");
        header("Content-type: application/zip"); 
        header("Content-Disposition: attachment; filename=" . $archive_file_name . "");
        header("Pragma: no-cache");
        header("Expires: 0");
        readfile("E:\Downloads/" . $archive_file_name);
        ob_clean();
        flush();
        exit;
    } else {
        exit("Could not find Zip file to download");
    }
}
$fileNames = array(
    'D:\\xampp\htdocs\BE\Multimedia/' . $fullName,
    'D:\\xampp\htdocs\BE\Decrypt/' . $decrypt_file
);
$zip_file_name = $actualName . '.zip';
$file_path = dirname("E:\Downloads") . '/';
zipFilesDownload($fileNames, $zip_file_name, $file_path);

Please suggest some solutions.


Solution

  • The problem looks to be this line:

    $file_path = dirname("E:\Downloads") . '/';
    

    The dirname function "Returns parent directory's path". This means that $file_path will be E:\.

    In your function you are using $file_path in the $zip->addFile() method, to refer to the file that should be added to the ZIP archive.

    In other words, if you have an array of files, like:

    $files = array(
        'file1.txt',
        'file2.txt',
        'file3.txt',
    );
    

    Then the files that will be added to the archive will be:

    E:\file1.txt
    E:\file2.txt
    E:\file3.txt
    

    What you probably want is to have these files added:

    E:\Downloads\file1.txt
    E:\Downloads\file2.txt
    E:\Downloads\file3.txt
    

    As far as I can see, to fix your code you simply need to not use dirname(), like this:

    $file_path = "E:\Downloads\\";