Zip entry open: примеры (PHP)
zip_entry_open(resource zip, resource zip_entry, string mode): boolФункция zip_entry_open
Функция zip_entry_open() открывает для чтения запись в ZIP-архиве. Этот метод используется при работе с модулем Zip (до PHP 8.0.0). Он готовит дескриптор для последующего чтения данных из конкретного элемента архива.
Использование функции актуально при необходимости извлечь содержимое файла из ZIP-архива вручную, пошагово обрабатывая элементы. Это часть процедурного API для работы с ZIP.
- zip_entry (resource) — ресурс записи ZIP, полученный с помощью zip_read().
- mode (string) — режим открытия. В контексте ZIP поддерживается, как правило, только чтение ("rb").
- flags (int) — опциональный параметр, зарезервированный для будущего использования.
Функция возвращает true в случае успеха или false при ошибке.
Простые примеры использования
Открытие элемента архива для последующего чтения.
$zip = zip_open('archive.zip');
if ($zip) {
while ($entry = zip_read($zip)) {
if (zip_entry_open($zip, $entry, "rb")) {
echo "Элемент открыт: " . zip_entry_name($entry) . "\n";
zip_entry_close($entry);
}
}
zip_close($zip);
}Элемент открыт: document.txt Элемент открыт: image.jpg
Обработка ситуации, когда открытие записи не удалось.
$zip = zip_open('archive.zip');
if ($zip) {
$entry = zip_read($zip);
if ($entry) {
if (!zip_entry_open($zip, $entry, "rb")) {
echo "Не удалось открыть элемент архива.";
} else {
echo "Элемент открыт успешно.";
zip_entry_close($entry);
}
}
zip_close($zip);
}Элемент открыт успешно.
Похожие функции в PHP
Объектно-ориентированный интерфейс для работы с ZIP-архивами, появившийся в PHP 5.2.0 и ставший предпочтительным. Он предлагает более удобные методы, такие как extractTo(), getFromName().
Устаревшая процедурная группа функций: zip_read(), zip_entry_name(), zip_entry_filesize(), zip_entry_read(), zip_entry_close(). Использовались вместе с zip_entry_open(). В PHP 8.0.0 модуль Zip, предоставляющий эти функции, переведен в статус устаревшего.
Класс ZipArchive является основным для новых проектов на PHP из-за более богатого API и активной поддержки. Процедурные функции, включая zip_entry_open(), считаются устаревшими (deprecated) и их следует избегать.
Аналоги в других языках
Класс ZipFile предоставляет методы open() для чтения конкретного файла в архиве и read() для получения данных.
import zipfile
with zipfile.ZipFile('archive.zip', 'r') as zf:
with zf.open('document.txt') as entry:
content = entry.read()
print(content.decode('utf-8'))Содержимое текстового файла.
Сторонний пакет adm-zip позволяет легко извлекать записи. Аналогом открытия записи является получение записи и её буфера данных.
const AdmZip = require('adm-zip');
const zip = new AdmZip('archive.zip');
const zipEntry = zip.getEntry('document.txt');
const content = zipEntry.getData().toString('utf8');
console.log(content);Содержимое текстового файла.
В отличие от процедурного подхода PHP, современные реализации в других языках обычно используют объектно-ориентированные интерфейсы, которые инкапсулируют состояние архива и не требуют ручного открытия и закрытия каждого элемента по отдельности.
Типичные ошибки
Ошибка возникает, если переданный ресурс не является корректным ресурсом ZIP-записи.
$zip = zip_open('archive.zip');
$entry = zip_read($zip);
zip_entry_close($entry); // Закрыли запись
// Попытка открыть уже закрытую запись
$result = zip_entry_open($zip, $entry, "rb");
var_dump($result);Warning: zip_entry_open(): supplied resource is not a valid Zip Entry resource bool(false)
Попытка чтения из архива, который не был успешно открыт.
$zip = zip_open('nonexistent.zip');
$entry = zip_read($zip); // $zip будет false при ошибке
if ($entry) {
zip_entry_open($zip, $entry, "rb");
}Warning: zip_read() expects parameter 1 to be resource, bool given
Использование режима, отличного от "rb", хотя для чтения ZIP-записей поддерживается только он.
$zip = zip_open('archive.zip');
$entry = zip_read($zip);
$result = zip_entry_open($zip, $entry, "wb"); // Неверный режим
var_dump($result);bool(false)
Изменения в версиях PHP
Модуль Zip, предоставляющий процедурные функции, включая zip_entry_open(), переведен в статус устаревшего (deprecated). Его использование вызовет уведомление об устаревании (E_DEPRECATED). Для создания и чтения ZIP-архивов следует использовать класс ZipArchive.
До PHP 8.0.0 функция была частью стандартного модуля Zip и не вызывала предупреждений. Специфических изменений в сигнатуре или поведении функции в течение её жизненного цикла не зафиксировано.
Расширенные примеры
Чтение содержимого файла из архива частями с помощью zip_entry_read().
$zip = zip_open('archive.zip');
if ($zip) {
while ($entry = zip_read($zip)) {
$name = zip_entry_name($entry);
if (zip_entry_open($zip, $entry, "rb")) {
$totalSize = zip_entry_filesize($entry);
echo "Чтение: $name ($totalSize байт)\n";
$buffer = '';
// Чтение блоками по 1024 байта
while ($data = zip_entry_read($entry, 1024)) {
$buffer .= $data;
}
echo "Прочитано " . strlen($buffer) . " байт.\n\n";
zip_entry_close($entry);
}
}
zip_close($zip);
}Чтение: large_file.bin (5242880 байт) Прочитано 5242880 байт.
Поиск элемента с определённым именем и его извлечение во временный файл.
function extractFileFromZip($zipPath, $searchFileName) {
$zip = zip_open($zipPath);
if (!is_resource($zip)) return false;
$found = false;
while ($entry = zip_read($zip)) {
if (zip_entry_name($entry) === $searchFileName) {
if (zip_entry_open($zip, $entry, "rb")) {
$content = zip_entry_read($entry, zip_entry_filesize($entry));
file_put_contents("/tmp/" . $searchFileName, $content);
zip_entry_close($entry);
$found = true;
break;
}
}
}
zip_close($zip);
return $found;
}
$result = extractFileFromZip('archive.zip', 'config.json');
echo $result ? 'Файл извлечен' : 'Файл не найден';Файл извлечен
Функция zip_entry_open() работает с записями, представляющими файлы. Записи, соответствующие директориям, имеют размер 0 и их открытие не требуется.
$zip = zip_open('archive.zip');
if ($zip) {
while ($entry = zip_read($zip)) {
$name = zip_entry_name($entry);
$size = zip_entry_filesize($entry);
// Проверка, является ли запись файлом (не директорией)
if ($size > 0 && substr($name, -1) !== '/') {
if (zip_entry_open($zip, $entry, "rb")) {
echo "Файл: $name (открыт)\n";
zip_entry_close($entry);
}
} else {
echo "Директория или пустой файл: $name (пропущено открытие)\n";
}
}
zip_close($zip);
}Директория или пустой файл: folder/ (пропущено открытие) Файл: folder/document.txt (открыт)