When using PHP to process ZIP compressed files, zip_read() is a common function that reads entries in compressed files one by one. However, in practical applications, many developers are prone to errors when using this function in loops, resulting in failed reading or incorrect logic. This article will explain in detail how to correctly use zip_read() to read all files in a compressed package.
PHP provides a set of functions related to ZIP file operations, such as zip_open() , zip_read() , and zip_entry_read() . Where, zip_read() is used to read entries from the open ZIP file resource in turn.
A typical code structure for reading compressed file contents is as follows:
<code> $zip = zip_open("example.zip"); if (is_resource($zip)) { while ($entry = zip_read($zip)) { echo "Name: " . zip_entry_name($entry) . "\n"; if (zip_entry_open($zip, $entry, "r")) { $contents = zip_entry_read($entry, zip_entry_filesize($entry)); echo "Contents: " . $contents . "\n"; zip_entry_close($entry); } } zip_close($zip); } else { echo "Cannot open ZIP file"; } </code>In the above code, zip_open() opens the compressed package, and zip_read() reads the entries one by one in the while loop until there are no more entry.
zip_read() is not continuously called in the loop
Some developers mistakenly think that they can read all entries at once, or try to use the foreach structure to manipulate zip_read() , which is not feasible. zip_read() is a sequential read function that must be placed in a while loop to iterate everything correctly.
Entry or ZIP file not closed
Forgot to call zip_entry_close() and zip_close() can lead to resource leakage, especially when dealing with large files or multiple ZIP packages.
Unhandled encoding issues of files in compressed packages
If the ZIP file contains a non-UTF-8 encoded file name, it may cause zip_entry_name() to display garbled code. You can use mb_convert_encoding() to transcoding:
<code> $filename = mb_convert_encoding(zip_entry_name($entry), "UTF-8", "CP936"); </code>Suppose we have an uploaded ZIP file, we want to decompress and save all files to the local uploads/ directory:
<code> $zip = zip_open($_FILES['file']['tmp_name']); if (is_resource($zip)) { while ($entry = zip_read($zip)) { $name = zip_entry_name($entry); $save_path = "uploads/" . basename($name); if (zip_entry_open($zip, $entry, "r")) {
$contents = zip_entry_read($entry, zip_entry_filesize($entry));
file_put_contents($save_path, $contents);
zip_entry_close($entry);
}
}
zip_close($zip);
echo "Decompression is complete";
} else {
echo "Uploaded file cannot be opened";
}
</code>
When deploying online, remember to verify the path, permissions and handle it safely to prevent path traversal (Directory Traversal) attacks.
If you are not sure if zip_read() returns entry correctly, you can add a debug statement:
<code> var_dump($entry); </code>In addition, you can also print the file name to confirm the parsed content:
<code> echo "Reading file:" . zip_entry_name($entry) . "\n"; </code>When reading ZIP files using zip_read() in PHP, be sure to pay attention to the following points:
Use while ($entry = zip_read($zip)) loop;
Use zip_entry_open() and zip_entry_close() after each read;
Finally, call zip_close() to close the resource;
Pay attention to file name encoding and directory security issues.