How to Upload and Unpack a Zip File using PHP
When you’re emailing or uploading larger files, it always makes sense to compress them first. This decreases file size and also helps avoid file corruption during transfer. The most common compressed file you will encounter is the zip file, since most operating systems come with a basic utility to quickly zip and unzip files. Creating a small function to upload a zip file to your server and unpack in the process isn’t as complicated as you might think.
First let’s create a simple form that will allow us to browse our computer and upload a zip file.
<form enctype="multipart/form-data" method="post" action=""> <label>Choose a zip file to upload: <input type="file" name="zip_file" /></label> <br /> <input type="submit" name="submit" value="Upload" /> </form> |
Now comes the uploader function:
<?php if($_FILES["zip_file"]["name"]) { $filename = $_FILES["zip_file"]["name"]; $source = $_FILES["zip_file"]["tmp_name"]; $type = $_FILES["zip_file"]["type"]; $name = explode(".", $filename); $accepted_types = array('application/zip', 'application/x-zip-compressed', 'multipart/x-zip', 'application/x-compressed'); foreach($accepted_types as $mime_type) { if($mime_type == $type) { $okay = true; break; } } $continue = strtolower($name[1]) == 'zip' ? true : false; if(!$continue) { $message = "The file you are trying to upload is not a .zip file. Please try again."; } $target_path = "/home/var/yoursite/httpdocs/".$filename; // change this to the correct site path if(move_uploaded_file($source, $target_path)) { $zip = new ZipArchive(); $x = $zip->open($target_path); if ($x === true) { $zip->extractTo("/home/var/yoursite/httpdocs/"); // change this to the correct site path $zip->close(); unlink($target_path); } $message = "Your .zip file was uploaded and unpacked."; } else { $message = "There was a problem with the upload. Please try again."; } } ?> |
To make sure the success and error messages appear, we will also have to add to short pieces of PHP code:
<?php if($message) echo "<p>$message</p>"; ?> |
Putting it all together into a PHP file would look like this:
<?php if($_FILES["zip_file"]["name"]) { $filename = $_FILES["zip_file"]["name"]; $source = $_FILES["zip_file"]["tmp_name"]; $type = $_FILES["zip_file"]["type"]; $name = explode(".", $filename); $accepted_types = array('application/zip', 'application/x-zip-compressed', 'multipart/x-zip', 'application/x-compressed'); foreach($accepted_types as $mime_type) { if($mime_type == $type) { $okay = true; break; } } $continue = strtolower($name[1]) == 'zip' ? true : false; if(!$continue) { $message = "The file you are trying to upload is not a .zip file. Please try again."; } $target_path = "/home/var/yoursite/httpdocs/".$filename; // change this to the correct site path if(move_uploaded_file($source, $target_path)) { $zip = new ZipArchive(); $x = $zip->open($target_path); if ($x === true) { $zip->extractTo("/home/var/yoursite/httpdocs/"); // change this to the correct site path $zip->close(); unlink($target_path); } $message = "Your .zip file was uploaded and unpacked."; } else { $message = "There was a problem with the upload. Please try again."; } } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Untitled Document</title> </head> <body> <?php if($message) echo "<p>$message</p>"; ?> <form enctype="multipart/form-data" method="post" action=""> <label>Choose a zip file to upload: <input type="file" name="zip_file" /></label> <br /> <input type="submit" name="submit" value="Upload" /> </form> </body> </html> |
Zip File Icon: Ritesh Ranjan



Hi, great tutorial, thank you.
When I open the page in the browser I get this error: Notice: Undefined index: zip_file in /home/www/xxx.php on line 525.
How I can solve this.
Regards
Hi, just to give you complete information, the line 525 is
Thank you in advance
Regards
nice program this is working i like this, and thanks for your code
There is a very small error in line 18 in then last box, semicolon is missing.
i need the reverse of this program can you plz help me.
i need to upload a file that need to be change a zip and store in a folder for downloading.
Thanks. Fixed the error. Why don’t you just upload it as a zip file?
I don’t see where you defined a ZipArchive() class…? As seen in $zip = new ZipArchive();
Nicely done. I’ve got it set up and it’s working fine. One problem I’m running into is a duplicate version of the zip file is uploaded as well. So, there are two new directories… One is the name of the zip file and the other is titled _MACOSX and contains the duplicate copy of the first directory. Any thoughts?
Yup. That is due to the fact that you created your zip file using the Mac compless tool. It also stores some meta data about the archive. I use YemuZip on my Mac to create PC compatible zip files. Doing it this way will eliminate that _MACOSX directory.
Or, you could create a function which checks for that _MACOSX directory and deletes it if it exists.
Thanks for the code !….good 1..!
Please help me, I am getting following error:
Warning: chdir() [function.chdir]: open_basedir restriction in effect. File() is not within the allowed path(s): (/home/:/usr/lib/php:/tmp) in /home/a9030732/public_html/upload/index.php on line 249
have no idea what I was doing wrong(
I appear to be having a lot of the same issues as Bytes Land. The same message seems to pop up whenever I attempt to implement the Uploading Function. Am I perhaps doing something wrong? Do you know of any common issues that you think can be alleviated? I often work with coding with
So I don’t know really know if I’m doing anything wrong.
Thanks a bunch!!!
The error is due to the fact that you are running your PHP in safe mode and open_basedir protection is enabled as a security measure to prevent users from opening files or scripts located outside of their home directory.
GREAT!!!!!! THANK YOU SOOO MCH!!!!
can’t i upload it without extracting?
If you don’t want to extract it you can just upload it the same way you would any file.
This Worked For Me:
@chagi – remove these lines:
okay the top code failed… but the main part of it didn’t
Thanks for this useful code. It took me an hour to figure out that I was running PHP in safe mode, though. I should have read through the comments earlier.
@Vinny I tried to manipulate the top code you posted, but did not come up with any solutions. Were you able to fix it? I’ve just recently started using PHP, so my ambition may be running a few lengths ahead of my knowledge, but I have an additional question. Hopefully, it will make sense.
A response to a comment above recommended turning off safe mode as well as disabling open_basedir protection in order to have things work smoothly. I’m hoping to come across availability solutions that will remedy the issue. What sort of security functionality will I lose by doing this? Are there recommended manipulations that I can perform on open_basedir protection, or is it just “on/off”? Thanks for any help. Marc
Hi thanks so much for this post it is great! I had a question, any help would be grateful as I am still new at php. The uploading of a zip file and the decompressing of the file works great, but I can upload ANY file, not just zip files with this coding. Am I missing something? I am using the identical code.
Thanks in advance.
There is a code check to make sure it is a zip file. If not, the code exits.