php-zip
php-zip copied to clipboard
Iterating entries throws an exception when ->addEmptyDir() has been used
| Q | A |
|---|---|
| Library version(s) affected: | ^3.3 |
| PHP version(s): | 7.4.10 |
| OS (with bit depth): | ProductName: macOS ProductVersion: 11.1 BuildVersion: 20C5048k |
Description
Iterating entries throws an exception when ->addEmptyDir() has been used
How to reproduce
$zipFile = (new ZipFile())
->addEmptyDir('images/')
->addFromString('images/cheese.jpg', 'brie');
foreach ($zipFile as $filename) {
echo $filename;
}
No data for zip entry images/
Possible Solution
I can't wrap the foreach in a try catch because it doesn't continue iterating. Is this a bug or am I approaching this wrong? I'd expect it to iterate over the file list and $contents be null (as thats how the empty dirs are created) where it is a directory as opposed to throwing an exception.
Additional context
I am creating some zips in tests and I would like to create zips in similar formats to those i'm occasionally processing. For example, I'd tested various scenarios but then as soon as i used a real zip which had a file structure like the below it failed (for reasons unrelated to this library).
images/
images/foo.jpg
images/bar.jpg
I'd obviously like to write a test which simulates this scenario so I tried adding an empty dir which works, and i can see the images/ dir there if I $zipFile->getListFiles().
$zipFile->addEmptyDir('images/');
However, some of my other code uses
foreach ($zipFile as $filename => $contents) {
// ...
}
Which then throws an exception
No data for zip entry images/
Thanks very much for your time.
Edit:
I also just tried using an ArrayIterator
$zipFile = (new ZipFile())
->addEmptyDir('images/')
->addFromString('images/cheese.jpg', 'brie');
$iterator = new \ArrayIterator($zipFile);
echo $iterator->count(); // 0
Edit2:
I can iterate and catch like this as a workaround.
foreach ($zip->getListFiles() as $filename) {
try {
$contents = $zip->getEntryContents($filename);
dump($filename);
} catch (ZipException $e) {
}
}