Book HomePHP CookbookSearch this book

18.27. Program: Unzip

The unzip.php program, shown in Example 18-5, extracts files from a ZIP archive. It uses the pc_mkdir_parents( ) function which is defined in Section 19.11. The program also requires PHP's zip extension to be installed. You can find documentation on the zip extension at http://www.php.net/zip.

This program takes a few arguments on the command line. The first is the name of the ZIP archive it should unzip. By default, it unzips all files in the archive. If additional command-line arguments are supplied, it only unzips files whose name matches any of those arguments. The full path of the file inside the ZIP archive must be given. If turtles.html is in the ZIP archive inside the animals directory, unzip.php must be passed animals/turtles.html, not just turtles.html, to unzip the file.

Directories are stored as 0-byte files inside ZIP archives, so unzip.php doesn't try to create them. Instead, before it creates any other file, it uses pc_mkdir_parents( ) to create all directories that are parents of that file, if necessary. For example, say unzip.php sees these entries in the ZIP archive:

animals (0 bytes)
animals/frogs/ribbit.html (2123 bytes)
animals/turtles.html   (1232 bytes)

It ignores animals because it is 0 bytes long. Then it calls pc_mkdir_parents( ) on animals/frogs, creating both animals and animals/frogs, and writes ribbit.html into animals/frogs. Since animals already exists when it reaches animals/turtles.html, it writes out turtles.html without creating any additional directories.

Example 18-5. unzip.php

// the first argument is the zip file
$in_file = $_SERVER['argv'][1];

// any other arguments are specific files in the archive to unzip
if ($_SERVER['argc'] > 2) {
    $all_files = 0;
    for ($i = 2; $i < $_SERVER['argc']; $i++) {
        $out_files[$_SERVER['argv'][$i]] = true;
    }
} else {
    // if no other files are specified, unzip all files
    $all_files = true;
}

$z = zip_open($in_file) or die("can't open $in_file: $php_errormsg");
while ($entry = zip_read($z)) {
    
    $entry_name = zip_entry_name($entry);

    // check if all files should be unzipped, or the name of
    // this file is on the list of specific files to unzip
    if ($all_files || $out_files[$entry_name]) {

        // only proceed if the file is not 0 bytes long
        if (zip_entry_filesize($entry)) {
            $dir = dirname($entry_name);

            // make all necessary directories in the file's path
            if (! is_dir($dir)) { pc_mkdir_parents($dir); }

            $file = basename($entry_name);

            if (zip_entry_open($z,$entry)) {
                if ($fh = fopen($dir.'/'.$file,'w')) {
                    // write the entire file
                    fwrite($fh,
                           zip_entry_read($entry,zip_entry_filesize($entry)))
                        or error_log("can't write: $php_errormsg");
                    fclose($fh) or error_log("can't close: $php_errormsg");
                } else {
                    error_log("can't open $dir/$file: $php_errormsg");
                }
                zip_entry_close($entry);
            } else {
                error_log("can't open entry $entry_name: $php_errormsg");
            }
        }
    }
}

18.27.1. See Also

Section 18.26 for reading and writing zlib compressed files; Section 19.11 for the pc_mkdir_parents( ) function; documentation on the zip extension at http://www.php.net/zip.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.