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 for reading ZIP file entries. However, many developers encounter the problem of empty directories being lost 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 while ignoring directory entries, resulting in empty directories not being properly created.

This article will, with example code, detail how to use the zip_read() function to correctly identify and extract empty directories, preventing them from being lost and ensuring the extracted file structure is complete.


1. Problem Analysis

ZIP file entries include both files and directories, with directory entries typically ending with a /. If the entry name returned by zip_read() ends with a /, it indicates a directory. During normal extraction, if only the directories corresponding to files are created but empty directory entries are not processed, empty directories will be ignored.


2. Example Code Demonstration

Below is an example based on PHP’s native ZIP functions, demonstrating how to read a ZIP file, distinguish 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, first ensure directory exists
    $filePath = $extractTo . $entryName;
    $dir = dirname($filePath);
    if (!is_dir($dir)) {
        mkdir($dir, 0755, true);
    }

    // Read file content and write it
    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: Directly create the corresponding directory when a directory entry is encountered.

  • 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 multi-level directories.


4. Related Links

For more information about PHP Zip functions, please refer to the official manual: