Creating ZIP and TAR archives on the fly with PHP
(Page 5 out of 5)Streaming files
To stream a file to a user browser, and have it downloading instead of displaying the data, you have to send various headers using the header() function. This isn't necessary in our case, because there's a great function on PHPit that does this all automatically for us. The function, called force_download(), looks like this:
// File size not set?
if ($filesize == false OR !is_numeric($filesize)) {
$filesize = strlen($data);
}
// Mimetype not set?
if (empty($mimetype)) {
$mimetype = 'application/octet-stream';
}
// Make sure there's not anything else left
ob_clean_all();
// Start sending headers
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false); // required for certain browsers
header("Content-Transfer-Encoding: binary");
header("Content-Type: " . $mimetype);
header("Content-Length: " . $filesize);
header("Content-Disposition: attachment; filename=\"" . $name . "\";" );
// Send data
echo $data;
die();
}
function ob_clean_all () {
$ob_active = ob_get_length () !== false;
while($ob_active) {
ob_end_clean();
$ob_active = ob_get_length () !== false;
}
return true;
}
The function requires three parameters: the data of the file, in our case the data of our archive which we get from the create_archive() function, the name of the file, which is in our case something like 'myfile.zip', and the mimetype. This last parameter is used to tell the browser what type of file we're sending. If we're sending a zip file, the mimetype should be "application/zip" and if we're sending a tar.gz file it should "application/x-tar-gz". Let's put together our download script:
include ('pear/archive_zip.php');
include ('pear/Tar.php');
// Name of the archive
$name = (!empty($_GET['name'])) ? $name = $_GET['name'] : $name = 'script';
// Just some protection
$name = str_replace("\\\\", '', $name);
$name = str_replace("\\", '', $name);
$name = str_replace('/', '', $name);
// Type specified?
$type = (!empty($_GET['type'])) ? $type = $_GET['type'] : $type = 'zip';
if ($type != 'zip' AND $type != 'tar') { $type = 'zip'; }
// Add this script to the list
$list = array('download.php');
// Create the archive
$data = create_archive ($name, $list, $type);
if ($type == 'zip') {
$mimetype = 'application/zip';
$name .= '.zip';
} else {
$mimetype = 'application/x-tar-gz';
$name .= '.tar.gz';
}
// Send file
force_download ($data, $name, $mimetype);
die();
// … all the functions go here
?>
That's all. Click here to download the full script and that's also a live demo of the above example. The archive you'll be downloading is generated dynamically.
Conclusion
In this tutorial I've shown you how to create ZIP and TAR archives on the fly using PHP and two PEAR packages. Using these packages is really simple, but you have to workaround a few problems before you can really use them. The function I've given you in this tutorial works around most of these problems, and allows you to dynamically create archives in almost any situation.
There's still a problem with global paths, since these don't work, and the create_archive() function doesn't account for this. This is only a minor problem, and can easily be fixed. This is left as an exercise for the reader.
If you have any comments or questions on this tutorial, feel free to leave them in the comments below or join us at PHPit Forums to talk more about this tutorial and other PHP topics.
May 18th, 2006 at 12:34 am
[…] Link: http://phpit.net/article/creating-zip-tar-archives-dynamically-php/ […]
May 18th, 2006 at 12:36 am
[…] Link: http://phpit.net/article/creating-zip-tar-archives-dynamically-php/ Posted by Administrator on May 18th, 2006 Filed in tutorials, php, links, php […]
May 20th, 2006 at 6:03 am
[…] http://phpit.net/article/creating-zip-tar-archives-dynamically-php/ […]
June 12th, 2006 at 9:00 am
Hi,
This was very interesting and gave me lots of thoughs to create new things,,
thanks alot
July 5th, 2006 at 3:13 am
Hi, Thanks a lot for the detailed tutorial… I have one problem, although: When I executed your script, it simply downloads the actual “example.txt” file (zipped up) instead of the array of files. I’m very new to php so apologies for my ignorance in advance but is there something I’m missing?
July 23rd, 2006 at 5:23 pm
Hi, this is Andrew again and I am still having the same problem almost 3 weeks later. If I implement the script exactly “As is”, it runs perfectly fine and I download the zip file but it only has 1 file in it… the “example.txt” file. Any ideas? I can’t find any other zip file tutorials…
August 10th, 2006 at 2:00 pm
Just tried it and it worked fine, very good article. First it didn’t put any file in the zipfile altough i filed my filelist array correctly, but later I saw it was due to a mistake in filepaths (I forgot a directory in the path).
Andrew ->Did you check that your filepaths are OK?