Current Location: Home> Latest Articles> How to Use the zip_read() Function to Properly Extract Zip Files Containing Empty Directories and Avoid Losing Them

How to Use the zip_read() Function to Properly Extract Zip Files Containing Empty Directories and Avoid Losing Them

M66 2025-07-18

When handling ZIP files in PHP, the zip_read() function is a common method to read entries in a ZIP archive. However, many developers encounter the issue of empty directories disappearing when extracting ZIP files that contain them. This happens because empty directories do not contain files, and zip_read() by default only iterates over file entries, ignoring directory entries, which causes empty directories not to be properly created.

This article, with example code, will explain in detail how to use the zip_read() function to correctly identify and extract empty directories, preventing their loss and ensuring the extracted file structure remains complete.


1. Problem Analysis

Entries in a ZIP file include both files and directories. Directory entries typically end with a /. If the entry name returned by zip_read() ends with a /, it indicates a directory. When extracting normally, if only the directories containing files are created but empty directory entries are ignored, those empty directories will be lost.


2. Example Code Demonstration

Below is an example based on PHP’s native ZIP functions, demonstrating how to read a ZIP file, differentiate between files and directories, and correctly create empty directories.

<?php
$zipPath = 'archive.zip'; // Path to the ZIP file
$extractTo = 'output/';   // Extraction target directory
<p>$zip = zip_open($zipPath);<br>
if (!is_resource($zip)) {<br>
die("Unable to open ZIP file\n");<br>
}</p>
<p>while ($entry = zip_read($zip)) {<br>
$entryName = zip_entry_name($entry);</p>
if (substr($entryName, -1) === '/') {
    // Create empty directory
    $dirPath = $extractTo . $entryName;
    if (!is_dir($dirPath)) {
        mkdir($dirPath, 0755, true);
        echo "Created empty directory: $dirPath\n";
    }
} else {
    // File entry, ensure directory exists first
    $filePath = $extractTo . $entryName;
    $dir = dirname($filePath);
    if (!is_dir($dir)) {
        mkdir($dir, 0755, true);
    }

    // Read file content and write to disk
    if (zip_entry_open($zip, $entry)) {
        $fp = fopen($filePath, 'w');
        while ($data = zip_entry_read($entry, 1024)) {
            fwrite($fp, $data);
        }
        fclose($fp);
        zip_entry_close($entry);
        echo "Extracted file: $filePath\n";
    }
}

}

zip_close($zip);
?>


3. Key Points Summary

  • Identify directory entries: Use zip_entry_name() to get the entry name. Directory entries usually end with a /.

  • Create empty directories: When encountering a directory entry, create the corresponding directory directly.

  • Create files and their parent directories: For file entries, ensure the parent directory exists before writing the file content.

  • Permissions and recursive creation: Set the third parameter of mkdir() to true to recursively create nested directories.


4. Related Links

For more documentation on PHP Zip functions, you can refer to the official manual: