I'm generating a set of HTML, CSS, and image files and I'm using ZipArchive to compress them into a zip file. I've confirmed that the generated assets are valid, but when I attempt to zip the set of files, the resulting archive file is not able to be opened.
I'm not getting any errors in the PHP and when I echo $zip->close()
it returns true which I assume to mean that it was able to write to and save the file without issue. Opening the zip with the mac Archive Utility throws this error:
"Unable to expand "filename.zip" into "Downloads". (Error 21 - Is a directory.)
What might be wrong here?
Here is the entire PHP script:
<?php
$ref = $_SERVER["HTTP_REFERER"];
$html = $_REQUEST['html'];
$images = $_REQUEST['images'];
$folder = uniqid();
$prepped = str_replace($ref.'server/php/files/', 'images/', $html);
mkdir("./runways/$folder", 0777);
mkdir("./runways/$folder/images", 0777);
mkdir("./runways/$folder/css", 0777);
file_put_contents('./runways/'.$folder.'/index.html',$prepped);
copy('../../css/runway.css', './runways/'.$folder.'/css/runway.css');
foreach($images as $image) {
$i = urldecode(str_replace($ref.'server/php/files/', '', $image));
$idata = file_get_contents('./files/'.$i);
file_put_contents('./runways/'.$folder.'/images/'.$i, $idata);
}
//echo $ref.'server/php/runways/'.$folder.'/';
$sourcefolder = './runways/'.$folder.'/';
$zipfilename = $folder.'.zip';
$dirlist = new RecursiveDirectoryIterator($sourcefolder);
$filelist = new RecursiveIteratorIterator($dirlist);
ini_set('max_execution_time', 5000);
$zip = new ZipArchive();
if ($zip->open('./zips/'.$zipfilename, ZIPARCHIVE::CREATE) !== TRUE) {
die ("Could not open archive");
}
foreach ($filelist as $key=>$value) {
$zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key");
}
$zip->close();
echo $ref.'server/php/zips/'.$zipfilename;
?>
A little background: I have chosen for my website to be wiped, and I have downloaded public_html as a zip file. I was a bit scared I wouldn't be able restore my website once it has been reset.
A quick solution (and the one that worked for me) is to use an app from the App Store called The Unarchiver. I had this same issue when using a file compressed from the cPanel file manager, and The Unarchiver seemed to fix it.
The archive you're creating includes current working directories and parent directories (filenames "." and ".."), which you should leave out. For example if you view the contents of an archive the original code creates, you'll see something like this:
$ unzip -l 54b69fbd2de29.zip
Archive: 54b69fbd2de29.zip
Length Date Time Name
-------- ---- ---- ----
0 01-14-15 09:56 ./runways/54b69fbd2de29/.
0 01-14-15 09:56 ./runways/54b69fbd2de29/..
0 01-14-15 09:56 ./runways/54b69fbd2de29/css/.
0 01-14-15 09:56 ./runways/54b69fbd2de29/css/..
12 01-14-15 09:56 ./runways/54b69fbd2de29/css/runway.css
0 01-14-15 09:56 ./runways/54b69fbd2de29/images/.
0 01-14-15 09:56 ./runways/54b69fbd2de29/images/..
26 01-14-15 09:56 ./runways/54b69fbd2de29/images/image1.jpg
31 01-14-15 09:56 ./runways/54b69fbd2de29/images/image2.jpg
6 01-14-15 09:56 ./runways/54b69fbd2de29/index.html
-------- -------
75 10 files
You don't want "./runways/54b69fbd2de29/." or "./runways/54b69fbd2de29/..", etc. Here's one way to fix this, change the final foreach to the following (note also that you don't need $key=>$value, just $key):
foreach ($filelist as $key) {
if (!preg_match('/\/\.{1,2}$/',$key)){
$zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key");
}
}
The resulting archive is valid, and looks like this:
unzip -l 54b6a39d55a63.zip
Archive: 54b6a39d55a63.zip
Length Date Time Name
-------- ---- ---- ----
12 01-14-15 10:13 ./runways/54b6a39d55a63/css/runway.css
26 01-14-15 10:13 ./runways/54b6a39d55a63/images/image1.jpg
31 01-14-15 10:13 ./runways/54b6a39d55a63/images/image2.jpg
6 01-14-15 10:13 ./runways/54b6a39d55a63/index.html
-------- -------
75 4 files
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With