Tuesday, July 29, 2014

Handling Zip Archives in PHP - II

In our previous article Handling Zip Archives in PHP - I, we learned about how to create ZIP archive in PHP. In this discussion, we would learn how to extract files from an Archive.

Check out our first code below, this just takes a ZIP Archive and extracts all files and folders from it.

<?php
// First Create a new Object of the class ZipArchive
$archive = new ZipArchive;

// Now OPEN Archive
$result = $archive->open("our_zip.zip");

// Check if the Archive was created successfully
if($result == 1)
{
  // Extract to current Folder
  $archive->extractTo('.');

  // Close the Archive
  $archive->close();
}
else
{
  echo "Archive creation Error [Error code : $result]";
}
?>

The code above is quite self-explanatory. The extractTo() method takes 2 parameters, first being the target folder where it should extract; second parameter is for specifying filenames only which we want to extract from the Archive. We would see an example soon. But before that, check the statement :

$archive->extractTo('.');

The character "." means current folder, ".." means parent folder. However this statement could have been written as shown below ::

<?php
// Extract to Current Working Folder
$archive->extractTo(getcwd());

// Extract to 'test' folder in the current working folder.
//'test' folder will be created if does not exist.
$archive->extractTo("test");  
?>

So, we know how to create an archive and extract files from it. Next we would try to modify the archive.

Here, we are going to rename a file inside the archive. Check out the statement ..

<?php
// This renames test.jpg to tester.jpg within 'images' folder
$zip->renameName('images/test.jpg','images/tester.jpg');
?>

However, we can move a file inside the Archive while renaming. Check the statement below ::

<?php
// This renames test.jpg to tester.jpg within 'images' folder
$zip->renameName('images/test.jpg','tester.jpg');
?>

The above statement move the file 'images/test.jpg' and renames it to 'tester.jpg' and saves it at the root level within the Archive. Similarly we can rename folders and move them accordingly.

Next, let's check out how we can delete files/folders from within a ZIP archive.

<?php
// Delete a file
$archive->deleteName("images/test.jpg");

// Delete a folder
$archive->deleteName("images/");
?>

While deleting a folder, we need to make sure that the name is followed by a "/" character. Secondly, only empty folders can be removed.

To set a comment for the Archive, we need to use setArchiveComment() method.

<?php
// Set the Archive Comment
$archive->setArchiveComment('this is a test comment');

// Get the Archive Comment
$comment = $archive->getArchiveComment();
?>

Next we can read each file within the Archive. Check the statement below ::

<?php
// Read File Content
$file_content = $archive->getFromName('a.txt');

// Print the Content
echo $file_content;
?>

We can get property of individual items within the Archive ::

<?php
// Get file stats
$data = $archive->statName('a.txt');

// Print
print_r($data);
?>

And here is the ourput :: 

Array
(
    [name] => a.txt
    [index] => 9
    [crc] => -1815353990
    [size] => 177045
    [mtime] => 1406113612
    [comp_size] => 378
    [comp_method] => 8
)

It shows that the file size is 177045 bytes which was compressed to 378 bytes.

All files/folders in the Archive has an index number. So, we can delete/rename or get statics of file or do other stuffs with that index number also. Let's check that out. In the example below, we show the list of all the items inside the Archive.

<?php
// LOOP thru files
for ($j = 0; $j < $archive->numFiles; $j++)
{
   // GET filename
   $filename = $archive->getNameIndex($j);
  echo "<br>$filename";
}
?>

Check the Output ::

tester.jpg
images/contact.jpg
images/spinning.gif
images/responsive.png
images/scan0001.jpg
images/test_image.jpg
e.txt
a.txt
b.txt
c.txt
d.txt

See, the code above has listed all the files inside any sub-folders. The ZipArchive object property numFiles (used as $archive->numFiles) holds the total number of files inside the Archive.

Some more functions which take file index number ::

$archive->statIndex(index_number) => Get file statistics
$archive->renameIndex(index_number) => Rename a file
$archive->deleteIndex(index_number) => Delete a file
$archive->getFromIndex(index_number) ==> Get contents of a file

If we want to revert all the changes we did to an item within the Archive, we can use these methods ::

$archive->unchangeName("a.txt");
$archive->unchangeIndex(index_number);

No comments: