Download of .Zip File Runs a Corrupted File PHP

Download of .zip file runs a corrupted file php

This issue can have several causes. Maybe your file is not found or it can not be read and thus the file’s content is just the PHP error message. Or the HTTP header is already sent. Or you have some additional output that then corrupts your file’s content.

Try to add some error handling into your script like this:

$file='../downloads/'.$filename;
if (headers_sent()) {
echo 'HTTP header already sent';
} else {
if (!is_file($file)) {
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
echo 'File not found';
} else if (!is_readable($file)) {
header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
echo 'File not readable';
} else {
header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: Binary");
header("Content-Length: ".filesize($file));
header("Content-Disposition: attachment; filename=\"".basename($file)."\"");
readfile($file);
exit;
}
}

Force download corrupts ZIP file

It might be an encoding problem. Try encoding it with Base64.

Header:
header('Content-Transfer-Encoding: base64');

Then, to throw the file base64_encoded()ed to the browser, try the following:

ob_start(); // Starts output buffering.
readfile($fileName); // "Outputs" the file.
$content = ob_get_clean(); // Grabs the output and assigns it to a variable.
print base64_encode($content); // Encodes and prints the content to the browser.

Note that simply base64_encode(readfile($fileName)) won't work because readfile() outputs data but doesn't return it.

Hope it helps!

Codeigniter ZIP file download corrupted

From what i know and what codeigniter's documentation is saying:

$path = '/var/www/html/uploads/'.$unique.'/';

  • $this->zip->read_dir($path)

    Permits you to compress a folder (and its contents) that already exists somewhere on your server. Supply a file path to the directory and the zip class will recursively read it and recreate it as a Zip archive. All files contained within the supplied path will be encoded, as will any sub-folders contained within it.

Basically you are creating a zip with everything starting from /var and ending with the files in the $unique folder, something is bound to be wrong ...

I recommend setting the second parameter to false, as the documentation specifies:

If you want the tree preceding the target folder to be ignored you can pass FALSE (boolean) in the second parameter.

  • $this->zip->read_dir($path, FALSE)

    This will create a ZIP with the folder "$unique" inside, then all sub-folders stored correctly inside that, but will not include the folders /var/www/html/uploads.

I also suggest/recommend, for better control of data and i believe fewer resources, to use:

  • $this->zip->add_data() instead of fopen() and $this->zip->read_dir()

Example:

public function downloadPackage($unique) {
$this->load->library('zip');

$text = $this->syndication_m->getTextForContent($unique);

$this->zip->add_data('copy-'.$unique.'.txt', $text);
$this->zip->download('dl-'.$unique.'.zip');
}

NOTE: Do not display any data in the controller in which you call this function since it sends various server headers that cause the download to happen and the file to be treated as binary.

--------------- EDIT ---------------

Unless you want to add to the zip whatever files are in the $unuqie directory, there is no use for $this->zip->read_dir().

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Testing extends CI_Controller {
public function downloadPackage($unique = '') {
$this->load->library('zip');

$unique = '4ts5yegq;';
$text = 'I am zorro ...';

$this->zip->add_data('copy-'.$unique.'.txt', $text);
$this->zip->download('dl-'.$unique.'.zip');
}
}

PHP readfile() causing corrupt file downloads

First of all, as some people pointed out on the comments, remove all spaces before the opening PHP tag (<?php) on the first line and that should do the trick (unless this file is included or required by some other file).

When you print anything on the screen, even a single space, your server will send the headers along with the content to be printed (in the case, your blank spaces). To prevent this from happening, you can:

a) not print anything before you're done writing the headers;

b) run an ob_start() as the first thing in your script, write stuff, edit your headers and then ob_flush() and ob_clean() whenever you want your content to be sent to the user's browser.

In b), even if you successfully write your headers without getting an error, the spaces will corrupt your binary file. You should only be writing your binary content, not a few spaces with the binary content.

The ob_ prefix stands for Output Buffer. When calling ob_start(), you tell your application that everything you output (echo, printf, etc) should be held in memory until you explicitly tell it to 'go' (ob_flush()) to the client. That way, you hold the output along with the headers, and when you are done writing them, they will be sent just fine along with the content.



Related Topics



Leave a reply



Submit