Page 1 of 1

Zip and Download a folder

Posted: Wed Nov 21, 2012 9:00 am
by nyo
Hi,

I am working on a script to create a .zip archive from a folder and download it. So far, I have the following, which creates and downloads a .zip archive of a pre-defined number of files in an array.
$files = array('file1.txt', 'file2.txt', 'file3.txt');
$archive = 'archive.zip';
$zip = new ZipArchive;
$zip->open($archive, ZipArchive::CREATE);
foreach ($files as $file) {
  $zip->addFile($file);
}
$zip->close();

header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$archive);
header('Content-Length: '.filesize($archive));
readfile($archive);
unlink($archive);
How should I modify it so that it will zip and download a folder that contains files and subfolders?

Thanks.

Re: Zip and Download a folder

Posted: Sun Nov 25, 2012 1:45 am
by jacek
You could use scandir() or glob() to list all of the files instead of using a static list.

Re: Zip and Download a folder

Posted: Wed Nov 28, 2012 8:53 am
by nyo
jacek wrote:You could use scandir() or glob() to list all of the files instead of using a static list.
Ok, I modified my script a little more as follows. It creates a .zip archive but it gives an error when you try to open it. Also, its size is 470b, whereas the files in it should be about 8kb.
<?php

// Location of directory to be zipped.
$dir = 'sample';

// Archive name.
$archive = 'sample.zip';

$zip = new ZipArchive;
$zip->open($archive, ZipArchive::CREATE);

$files = scandir($dir);
unset($files[0], $files[1]);
foreach ($files as $file) {
	$zip->addFile($dir.'/'.$file);
}
$zip->close();

header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$archive);
header('Content-Length: '.filesize($archive));
readfile($archive);
unlink($archive);
?>
The error I get is something like "'C:\Desktop\archive.zip' can't be opened as an archive file".

Re: Zip and Download a folder

Posted: Thu Nov 29, 2012 1:30 am
by jacek
That is probably caused by the ziping stuff causing a php error which makes the file invalid. comment out everything after $zip->close() and reload the page. That should show you the error instead of including it at the start of the file.

Re: Zip and Download a folder

Posted: Thu Nov 29, 2012 8:18 am
by nyo
jacek wrote:That is probably caused by the ziping stuff causing a php error which makes the file invalid. comment out everything after $zip->close() and reload the page. That should show you the error instead of including it at the start of the file.
I further modified the script:
<?php
$dir = 'sample';
$archive = 'sample.zip';

function create_zip($folder, &$zipFile, $subfolder = null) {
	$folder .= end(str_split($folder)) == "/" ? "" : "/";
	$subfolder .= end(str_split($subfolder)) == "/" ? "" : "/";
	echo 'Folder: '.$folder;
	echo '<br />';
	echo 'Subfolder: '.$subfolder;
	$handle = opendir($folder);
	while ($file = readdir($handle)) {
		if ($file != '.' && $file != '..') {
			if (is_file($folder.$file)) {
				if ($subfolder != null)
                    $zipFile->addFile($folder.$file, $subfolder.$file);
                else
                    $zipFile->addFile($folder.$file);
			} elseif (is_dir($folder.$file)) {
				$zipFile->addEmptyDir($file);
				create_zip($folder.$file, $zipFile, $file);
			}
		}
	}
}

$zip = new ZipArchive;
$zip->open($archive, ZIPARCHIVE::CREATE);
create_zip($dir, $zip);
$zip->close();

header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$archive);
header('Content-Length: '.filesize($archive));
readfile($archive);
unlink($archive);
?>
It still gives the same error when I try to open the zip file. I tried your suggestion and here is the error:

"Strict Standards: Only variables should be passed by reference"

for the following lines:
$folder .= end(str_split($folder)) == "/" ? "" : "/";
$subfolder .= end(str_split($subfolder)) == "/" ? "" : "/";

Re: Zip and Download a folder

Posted: Thu Nov 29, 2012 3:38 pm
by Temor
That just tells you that php doesn't like it when you pass a function as a parameter in another function.
You could split it up so that you only pass variables through, and the error would go away, but it's not necessary.

You can turn off strict mode and the error will disappear.
error_reporting(E_ALL ^ E_STRICT);