Zip entry open: примеры (PHP)

Использование функции zip_entry_open для работы с ZIP-архивами
Раздел: Архивация
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

Класс ZipArchive

Объектно-ориентированный интерфейс для работы с ZIP-архивами, появившийся в PHP 5.2.0 и ставший предпочтительным. Он предлагает более удобные методы, такие как extractTo(), getFromName().

Функции procedural Zip

Устаревшая процедурная группа функций: 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) и их следует избегать.

Аналоги в других языках

Python: модуль zipfile

Класс 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'))
Содержимое текстового файла.
JavaScript (Node.js): модуль adm-zip

Сторонний пакет 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

PHP 8.0.0

Модуль Zip, предоставляющий процедурные функции, включая zip_entry_open(), переведен в статус устаревшего (deprecated). Его использование вызовет уведомление об устаревании (E_DEPRECATED). Для создания и чтения ZIP-архивов следует использовать класс ZipArchive.

Более ранние версии

До PHP 8.0.0 функция была частью стандартного модуля Zip и не вызывала предупреждений. Специфических изменений в сигнатуре или поведении функции в течение её жизненного цикла не зафиксировано.

Расширенные примеры

Последовательное чтение данных из записи

Чтение содержимого файла из архива частями с помощью zip_entry_read().

Пример php
$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 байт.
Извлечение конкретного файла по имени

Поиск элемента с определённым именем и его извлечение во временный файл.

Пример php
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 и их открытие не требуется.

Пример php
$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 (открыт)

PHP zip_entry_open function comments

En
Zip entry open Open a directory entry for reading