Zip and Download a folder

Ask about a PHP problem here.
Post Reply
nyo
Posts: 124
Joined: Mon May 09, 2011 1:55 pm
Location: Mobile

Zip and Download a folder

Post 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.
User avatar
jacek
Site Admin
Posts: 3262
Joined: Thu May 05, 2011 1:45 pm
Location: UK
Contact:

Re: Zip and Download a folder

Post by jacek »

You could use scandir() or glob() to list all of the files instead of using a static list.
Image
nyo
Posts: 124
Joined: Mon May 09, 2011 1:55 pm
Location: Mobile

Re: Zip and Download a folder

Post 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".
User avatar
jacek
Site Admin
Posts: 3262
Joined: Thu May 05, 2011 1:45 pm
Location: UK
Contact:

Re: Zip and Download a folder

Post 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.
Image
nyo
Posts: 124
Joined: Mon May 09, 2011 1:55 pm
Location: Mobile

Re: Zip and Download a folder

Post 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)) == "/" ? "" : "/";
User avatar
Temor
Posts: 1186
Joined: Thu May 05, 2011 8:04 pm

Re: Zip and Download a folder

Post 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);
Post Reply