How to unzip or extract zip archieve files using PHP?

 

As you have seen earlier, I have posted an article How to create a ZIP file using PHP and MySQL. Today we are going to extract or unzip files from ZIP archieve using PHP. Using ZIP archieve you can store multiple files. You can create a .zip archieve files using compression or without compression. Suppose you have a ZIP archieve which contains multiple files in it and you want to unzip/extract all the files which exists inside the ZIP archieve to a different location. Below are the steps how to do it in php.

function.php
This file contains few functions which we will use later.

<?php
/*This function will check whether files are valid files*/
function ValidFileExtension(){
	return array('png','jpg','jpeg','gif');
}

/*Read all folder and files*/
function ReadAllFolderAndFiles($dir,&$file_list){
    $dir_and_files = scandir($dir);    
    foreach($dir_and_files as $df){
        if($df != '.' && $df != '..'){
			if(is_file($dir.'/'.$df) && $df!='Thumbs.db'){				
				$FileExt=getFileExtension($dir.'/'.$df);
				if(!in_array($FileExt,ValidFileExtension())){
					$file_list["INVALID_FILE"][]=$dir.'/'.$df;
				}else{
					$file_list["VALID_FILE"][]=$dir.'/'.$df;
				}				
			}
            if(is_dir($dir.'/'.$df)) ReadAllFolderAndFiles($dir.'/'.$df,$file_list);
        }
    }
	return $file_list;
}


/*This function will return zip extension file name*/
function getFileExtension($file_name){
	if(trim($file_name)!=''){
		$ext_part= pathinfo($file_name);
		$ext = strtolower($ext_part["extension"]);
		return $ext;
	}
}

/*This function will check whether uploaded file is a valid zip file*/
function IsValidZipFile($file_path) {
  if($file_path!=''){
	  $zip = zip_open($file_path);
	  if (is_resource($zip)) {		
			zip_close($zip); //Close the zip file after checking
			return true;
	  }else{
		return false;
	  }
   }
}

/*This function will Delete directory and all files under it recursively*/
function RecursiveDeleteDirectory($dir) {
	if(is_dir($dir)){
		foreach (scandir($dir) as $file) {
			if ($file != '.' && $file != '..') {
				if(is_dir($dir.'/'.$file)) {
					RecursiveDeleteDirectory($dir.'/'.$file);
				}else{
					if(is_file($dir.'/'.$file) && file_exists($dir.'/'.$file)){				
						unlink($dir.'/'.$file);			
					}
				}            
			}	
		}	
		return rmdir($dir);
	}
}

/*This function will removes all files from the folder*/
function DeleteAllFiles($dir){	
    $files = glob($dir.'*');// get all file names inside this directory	
	foreach($files as $file){
	  if(is_file($file))
		unlink($file); // delete file
	}
}
?>

The function.php file contains 6 functions. Lets describe in details. ValidFileExtension() function will validate those files extension which are defined inside this function. ReadAllFolderAndFiles() function will read all the folders and the files which are located under the ZIP archieve and if those have valid extensions then it stores them in the VALID_FILE array variable else stores all invalid files in the INVALID_FILE array variable and finally this function will return an array. Then the getFileExtension() function returns the file extension. IsValidZipFile() function checks whether uploaded ZIP is a valid ZIP archieve file. RecursiveDeleteDirectory() function recursively deletes all files and folders. Finally DeleteAllFiles function will delete all files from the given path.

index.php
This is a demo page to show how to validate the form and use the extract function.

<?php
$ShowError=array();	
$TotalUploadFiles=0;
if($_SERVER['REQUEST_METHOD']=='POST'){
	if (extension_loaded('zip')) {
	
		//validation
		 if(isset($_FILES['zip_file']) && (trim($_FILES['zip_file']['tmp_name'])=='')){
			 $ShowError[]="Upload zip file.";
		 }elseif(IsValidZipFile($_FILES["zip_file"]['tmp_name'])==false){
				$ShowError[]="Please upload zip file only.";			
		 }
		
		if(count($ShowError)<=0){
			//This should be absoluth folder path where zip file will upload
			$UploadZipFolderPath=$_SERVER["DOCUMENT_ROOT"]."/site/script/unzip/upload/";
			$file_destination=$UploadZipFolderPath.$_FILES['zip_file']['name'];
			if(move_uploaded_file($_FILES['zip_file']['tmp_name'],$file_destination)){
				$ExtractFolderName=$UploadZipFolderPath.basename($file_destination,".".getFileExtension($file_destination));
				
				$file_list=array();
				$ExtractFolderPath=$_SERVER["DOCUMENT_ROOT"]."/site/script/unzip/extract/";				
				$zip = new ZipArchive;
				if ($zip->open($file_destination) === TRUE) {
					
					$zip->extractTo($UploadZipFolderPath);
					$zip->close();
					chmod($file_destination, 0777);
					unlink($file_destination);
										
					$UploadedFileList=ReadAllFolderAndFiles($UploadZipFolderPath,$file_list);
					$TotalUploaded=count($UploadedFileList);
					if($TotalUploaded>0){
						
						
						//UnSuccess Uploaded Files
						$UnSuccessUploaded=$UploadedFileList["INVALID_FILE"];
						$TotalUnSuccess=count($UnSuccessUploaded);
						$UnSuccessArr=array();
						if($TotalUnSuccess>0){
							$ct=0;
							while($ct<$TotalUnSuccess){
							   $UnSuccessArr[]=basename($UnSuccessUploaded[$ct]);							   
							   $ct++;
							}
							
							if(count($UnSuccessArr)>0){
								$ShowError[]="These file(s) ". implode(',',$UnSuccessArr) . " are not a valid image file.
											  Remove these files and upload again.";
							}
						}else{
							$SuccessUploaded=$UploadedFileList["VALID_FILE"];
							$TotalSuccess=count($SuccessUploaded);
							if($TotalSuccess>0){
								$ct=0;
								while($ct<$TotalSuccess){
								   copy($SuccessUploaded[$ct],$ExtractFolderPath.basename($SuccessUploaded[$ct]));							   
								   $ct++;
								   $TotalUploadFiles++;
								}
							}
						}
						
						if(!is_dir($ExtractFolderName)){
							DeleteAllFiles($UploadZipFolderPath);							
						}else{							
							RecursiveDeleteDirectory($ExtractFolderName);
						}
					}					
			    }
			}
		}		
	}else{
		$ShowError[]="Zip extension is not loaded.";
	}
}
?>
<!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>How to extract ZIP file in PHP</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
  <table width="100%" border="0">
  <?php
  if(count($ShowError)>0 || $TotalUploadFiles>0){?>
  <tr>
      <td colspan="2" align="center">
	  <?php
	    if(count($ShowError)>0){
			echo implode("\n",$ShowError);
		}else if($TotalUploadFiles>0){
			$TotalUploadFiles . ' files uploaded successfully.';
		}
	  ?>
	  </td>
    </tr>
	<?php
	}
  ?>
    <tr>
      <td width="45%" align="right">Zip File: </td>
      <td width="55%" align="left"><input type="file" name="zip_file" /></td>
    </tr>
    <tr>
      <td colspan="2" align="center"><input type="submit" value="Upload" /></td>
    </tr>
  </table>
</form>
</body>
</html>

The above code contains a simple HTML form. If the file is uploaded and extracted successfully then it displays the success message else it will show all error messages. Once user submitted the form extension_loaded() function checks whether ZIP extension module is installed or not. If it is not installed then it will display an error else execute the next block of code. Next it checks whether uploaded file is a valid zip file. If there is no error it will execute next block of code. Set your absolute path on this variable i.e $UploadZipFolderPath where temporaryly zip file will stored. Once zip file will be uploaded in the destination folder the $ExtractFolderName variable will return the zip folder name without the .zip extension.

Next define your folder name where all extracted files will store on this variable i.e $ExtractFolderPath. Then the ZipArchive constructor is called and open() method of zip archieves opens an archieve for writing,reading or modifying. The most important thing is extractTo() function. This function extract all files to the destination folder. Then close() method closes the active archieve. After successfull extraction of the zip file, set file permission to 0777 using chmod() function so the script can delete the zip archieve from the folder. Here I have written this 2 line of codes because I don’t want to store the zip archieve once it is succefully extracted. Delete the zip files so the server gets some space.

Then ReadAllFolderAndFiles() function is used which is defined in the function.php file. It accepts 2 parameters, first one is the file path of the folder where all your zip files uploaded, second parameter is reference array variable. Next, after reading all files using this function it returns 2 array variables as I have discussed earlier. If there is any invalid file then it stores errors in this variable $ShowError else it copies all the files to the destination folder.

Finally DeleteAllFiles() and RecursiveDeleteDirectory() functions are used. You can create your zip archieve in 2 ways. Either you add all the files inside the zip archive without any folder or first you create a folder then add all files in it and finally create the zip archieve. DeleteAllFiles() function deletes all files if you have create the zip without any folder and RecursiveDeleteDirectory() function deletes all files and folders recursively.

COMMENTS ( 5 )

This is really fascinating, You’re an excessively professional blogger.
I have joined your rss feed and look ahead to searching for extra of your excellent post.

Additionally, I’ve shared your web site in my social networks

Reply

Hello to all, the contents present at this web site are
in fact remarkable for people experience, well, keep up the nice work fellows.

Reply

Thanks for the marvelous posting! I actually enjoyed reading it,
you may be a great author.I will guarantee that I bookmark your blog site and indeed will come back someday.
I want to encourage you continue your great job, have got a nice morning!

Reply

You actually make it seem quite simple along with your presentation however I to locate this topic being actually something that In my opinion I’d in no way understand.
It type of feels too complicated and extremely vast in my opinion.
I am just looking ahead with your next submit, I am going to make an effort to
receive the hold of this!

Reply

Leave a comment

SUBSCRIBE TO NEWSLETTER

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Categories