I am trying to show the file and directory contents of a zip file without extracting it. Zip library is not installed with PHP and I don't have permission to install it.
I am trying now to parse the output of unzip -l <zipfile>
to get the directory structure of the zip file together with other file information. I can easily get the file information by parsing the result line by line. However, I found it difficult to convert it a directory structure in array since I'm just a newbie in php. the structure is something like below (please ignore the syntax I'm just trying to show the structure). Subdirectories or sub files are placed inside the children index.
$file[0]['file_name'] = 'dir1',
$file[0]['children'] = array($subfile[0]['file_name'] = 'subdir1',
$subfile[0]['children'] = .....,
$subfile[1]['file_name'] = 'subdir1',
$subfile[1]['children'] = .....)
$file[1]['file_name'] = 'dir2',
$file[1]['children'] = array($subfile[0]['file_name'] = 'subdir1',
$subfile[0]['children'] = .....,
$subfile[1]['file_name'] = 'subdir1',
$subfile[1]['children'] = .....)
Below is the sample output of unzip -l <zipfile>
.
12363 08-18-2010 13:07 lsmaps/aka.gif
10299 03-10-2010 12:34 lsmaps/aob.gif
26095 03-10-2010 12:34 lsmaps/cba.gif
Would you know of better way of doing it?
Thanks
pclzip a pure PHP (read: you can just copy the files into your project) reader and writer for zip, like this:
require_once('pclzip.lib.php');
$archive = new PclZip('zipfile.zip');
var_export($archive->listContent());
To convert the flat information into a tree, you can use the following helper function:
function flatToTree($flat) {
$res = array();
foreach ($flat as $e) {
$parent =& $res;
$path = explode('/', $e['filename']);
for ($i = 0;$i < count($path) - 1;$i++) {
if (! array_key_exists($path[$i], $parent)) {
$parent[$path[$i]] = array('file_name'=>$path[$i],
'children'=>array());
}
$parent =& $parent[$path[$i]]['children'];
}
$basename = $path[count($path)-1];
if ($basename != '') { // A file, not a directory
$parent[$basename] = array('file_name' => $path[$i]);
}
}
return $res;
}
var_export(flatToTree($archive->listContents()));
Note that it uses associative arrays (or dictionary/maps) to allow faster access to the files by name. You can still iterate over it with foreach
. If you, however, must have numeric arrays, simply call array_values
on each element.