Developer

Create and edit TAR archives dynamically with PHP and PEAR

The Tape ARchive (TAR) format that is commonly used in UNIX for packaging multiple files together for easy distribution. PHP has the ability to read and create TAR archives via PEAR's Archive_Tar class. This tutorial shows you this class in action, illustrating how you can use it to dynamically create, edit and view TAR archives.

This article is also available as a TechRepublic download, which includes all of the code in a more manageable text file format.

If you've ever downloaded a widget for your UNIX system, you've already met TAR, the Tape ARchive format that is commonly used in UNIX for packaging multiple files together for easy distribution. This format is popular not only because the tools to create it exist on all UNIX systems, but also because it's particularly good at preserving the directory structure, permissions, and user and group information of the files it archives.

PHP comes with a wide variety of both built-in functions and external libraries to connect to, and work with, almost any file format you can name. In particular, it has the ability to read and create TAR archives via PEAR's Archive_Tar class. And in this tutorial, I'll show you this class in action, illustrating how developers can use it to dynamically create, edit and view TAR archives.

I'll assume here that you have a working Apache and PHP installation and that the PEAR Archive_Tar class has been correctly installed.

Note: You can install the PEAR Archive_Tar package directly from the Web, either by downloading it from or by using the instructions provided.

Creating TAR archives

Let's begin with a simple example: dynamically creating a TAR archive that contains a few other files. Start with the following script:

Listing A


<?php
include ('Archive/Tar.php');        // import class

$obj = new Archive_Tar('dummy.tar'); // name of archive

$files = array('mystuff/ad.gif',
               'mystuff/alcon.doc',
               'mystuff/alcon.xls');   // files to store in archive

if ($obj->create($files)) {
    echo 'Created successfully!';
} else {
    echo 'Error in file creation';
}
?>

This script is quite simple, but it's worth looking at it in detail:

  1. The first step is to create an instance of the Archive_Tar class, and initialize it with the path and name of the archive to be created. In this example, the archive is named dummy.tar and located in the current directory.
  2. Next, a list of all the files to be packaged, together with their disk locations, is saved to a PHP array. It's important to remember that the script (more precisely, the user the script runs as) must have permission to access these disk locations or else the archive creation process will fail.
  3. Finally, the create() method is used to collect the named files into a single TAR archive. This method accepts the array of file names as input and returns a Boolean value indicating whether or not the archive was successfully created. Remember that the script must have permission to write the file to the named disk location; if not, the create() method will fail and the archive will not be created.

To use the example script above, modify the contents of the $files array to reflect your local system configuration and try executing it, either at the command prompt or through your browser. If all goes well, the script should find and read your files into a single TAR archive named dummy.tar.

Viewing TAR archive contents

What about looking inside an existing TAR file? Archive_Tar comes with a listContent() method that provides detailed information on the individual components of a TAR package. Listing B shows you how to use it:

Listing B


<?php
include ('Archive/Tar.php');        // import class

$obj = new Archive_Tar('dummy.tar'); // name of archive

$files = $obj->listContent();       // array of file information

foreach ($files as $f) {
    foreach ($f as $k => $v) {
        echo "$k: $v\n";
    }
    echo "\n";
}
?>

The output of listContent() is a structured array of arrays, with each array element representing an individual file from the archive. Typically, each element holds information on the name of the corresponding file, its permission mode, IDs of its owner and group, its status, its size, and the time of last modification. It's fairly easy to extract this information with a loop and re-format it to make it more presentable, as the example above does. Here's a sample of the output:

checksum: 3872
filename: mystuff/alcon.doc
mode: 33206
uid: 433
gid: 106
size: 41472
mtime: 1140358031

Inserting files into existing TAR archives

For the more forgetful among us, the Archive_Tar class has the ability to insert new files into an existing archive via its add() method. To illustrate, let's go back to dummy.tar and try adding a new file to it (Listing C):

Listing C


<?php
include ('Archive/Tar.php');        // import class

if (file_exists('dummy.tar')) {
    $obj = new Archive_Tar('dummy.tar'); // name of TAR file
} else {
    die('File does not exist');
}

$files = array('otherstuff/logo.gif',
               'otherstuff/header.gif',
               'morestuff/berlin-bear.psd');   // additional files

if ($obj->add($files)) {
    echo 'Added successfully!';
} else {
    echo 'Error in file addition';
}
?>

The procedure to insert a file into an existing archive is very similar to that of creating a new archive: initialize a new Archive_Tar object referencing the archive, create an array holding the list of files to be added, and pass this array to the add() method. Like create(), add()returns a Boolean signal indicating whether or not the addition succeeded.

Extracting files from existing TAR archives

Once you've got the files into the archive, how do you get them out? With the extractList() method, obviously! This method lets you extract one or more files from an existing archive to a specified directory, as illustrated in Listing D:

Listing D


<?php

include ('Archive/Tar.php');        // import class

if (file_exists('dummy.tar')) {

    $obj = new Archive_Tar('dummy.tar'); // name of TAR file

} else {

    die('File does not exist');

}

$files = array('otherstuff/logo.gif',

               'mystuff/alcon.doc');   // files to extract

if ($obj->extractList($files, 'unpackaged/')) {

    echo 'Extracted successfully!';

} else {

    echo 'Error in file extraction';

}

?>

Here, an array of the files to be extracted is passed to the extractList() method, together with the name of the directory they should be extracted to. Note that the files will be extracted with their internal directory structure intact (although this behavior can be modified by passing special parameters to the extractList() method).

In addition to this type of selective extraction, you can also use the extract() method, which unpackages the entire archive and extracts all the files within it to a specified directory. If this directory does not exist, it will be created automatically by extract(), assuming of course that the script has permission to write to disk. Listing E shows you how:

Listing E


<?php
include ('Archive/Tar.php');        // import class

if (file_exists('dummy.tar')) {
    $obj = new Archive_Tar('dummy.tar'); // name of TAR file
} else {
    die('File does not exist');
}

if ($obj->extract('unpackaged/')) {
    echo 'Extracted successfully!';
} else {
    echo 'Error in file extraction';
}
?>

As the examples above illustrate, PEAR'sArchive_Tarclass is quite versatile and allows you to perform some fairly complex TAR actions with just a few lines of code. Hopefully, the sample scripts above sparked some ideas about how you can use this class in your daily development activities.

0 comments

Editor's Picks