I thought I conveniently could list any contents in a zip file using a glob pattern. But that didn't seem to work. Is there a way?
<?php
$contents = glob('zip://path/to/archive.zip#subdir/*.ext');
var_dump($contents);
The zip:// stream wrapper doesn't seem to return directory contents at all.
scandir('zip://path/to/archive.zip#subdir/'); // array(0){}
The documentation is not too helpful: https://www.php.net/manual/en/wrappers.compression.php
There are multiple problems here. glob() does not support stream wrappers. And the stream wrapper for zip:// does not have an implementation for listing directory contents.
So both the stream wrapper and glob() would need to be substituted.
What might be more convenient is to write a function that extracts data from a ZIPArchive() object and filter it using fnmatch():
function globzip($archive, $pattern, $flags = 0) {
$zip = new ZipArchive();
$zip->open($archive, ZipArchive::RDONLY);
$result = [];
for ($i = 0; $i < $zip->numFiles; $i++) {
$file = $zip->getNameIndex($i);
if (fnmatch($pattern, $file, $flags)) {
$result[] = $file;
}
}
return $result;
}
Can be used like this:
$files = globzip('/path/to/.zip', 'subdirectory/*.ext'));
https://www.php.net/manual/en/function.fnmatch.php https://www.php.net/manual/en/class.ziparchive