W3docs

zip_read()

Функция zip_read() в PHP читает следующую запись из открытого zip-архива. Устарела в PHP 8.0 — используйте ZipArchive.

⚠️ Уведомление об устаревшем API: Функция zip_read() и связанные с ней процедурные функции для работы с zip были удалены в PHP 8.0. Они требуют расширения ext-zip PECL и доступны только в PHP 7.4 и более ранних версиях. Для современных приложений на PHP рекомендуется класс ZipArchive.

Функция zip_read() читает следующую запись (отдельный файл или запись каталога) из открытого zip-архива. Она является частью устаревшего процедурного API PHP для работы с zip, в котором архив обходится по одной записи за раз: открываете архив с помощью zip_open(), последовательно вызываете zip_read() для перехода к следующим записям, а затем закрываете его с помощью zip_close().

Каждый успешный вызов возвращает ресурс записи zip — дескриптор, который передаётся функциям zip_entry_* для проверки или чтения этой записи. Когда записей больше нет, zip_read() возвращает false, что и завершает цикл. При ошибке вместо этого возвращается числовой код ошибки.

Синтаксис

Синтаксис функции zip_read() выглядит следующим образом:

Синтаксис функции zip_read() в PHP

resource|int|false zip_read(resource $zip)

$zip — ресурс архива, возвращённый функцией zip_open(). Возвращаемое значение — одно из следующих:

  • ресурс записи zip — есть запись для обработки;
  • false — достигнут конец архива;
  • целочисленный код ошибки — при чтении архива что-то пошло не так.

Зачем использовать цикл с zip_read()?

Процедурный API представляет собой курсор с односторонним движением вперёд: вызова «получить все записи» не существует. Вы читаете одну запись, выполняете с ней какие-либо действия (получаете её имя и размеры или извлекаете содержимое), а затем запрашиваете следующую. Это позволяет снизить использование памяти, поскольку в области видимости одновременно находится только одна запись, но также означает, что нельзя перейти к произвольной записи — необходимо обходить архив с самого начала.

Примеры использования

Пример: перечисление записей в zip-архиве

Этот цикл открывает архив и выводит метаданные для каждой содержащейся в нём записи:

Чтение записей zip-архива в PHP

$zip = zip_open("example.zip");
if (!is_resource($zip)) {
    throw new RuntimeException("Failed to open zip archive (error code: $zip)");
}
while ($zip_entry = zip_read($zip)) {
    echo "Name: " . zip_entry_name($zip_entry) . "\n";
    echo "Compressed Size: " . zip_entry_compressedsize($zip_entry) . "\n";
    echo "Uncompressed Size: " . zip_entry_filesize($zip_entry) . "\n";
}
zip_close($zip);

Код открывает example.zip с помощью zip_open(), а затем выполняет цикл, пока zip_read() продолжает возвращать ресурсы записей. Для каждой записи выводится имя с помощью zip_entry_name(), размер в сжатом виде с помощью zip_entry_compressedsize() и исходный размер с помощью zip_entry_filesize(). Наконец, zip_close() освобождает архив.

Пример: чтение содержимого записи

zip_read() только устанавливает текущую позицию на запись; чтобы прочитать реальные байты, необходимо открыть запись с помощью zip_entry_open() и получить данные с помощью zip_entry_read():

$zip = zip_open("example.zip");
if (is_resource($zip)) {
    while ($entry = zip_read($zip)) {
        if (zip_entry_open($zip, $entry, "r")) {
            $contents = zip_entry_read($entry, zip_entry_filesize($entry));
            echo zip_entry_name($entry) . ":\n" . $contents . "\n";
            zip_entry_close($entry);
        }
    }
    zip_close($zip);
}

Распространённые ошибки

  • Истинность значения в цикле. while ($entry = zip_read($zip)) работает, потому что корректный ресурс является истинным, а false завершает цикл. Однако при ошибке также возвращается целочисленный код — проверяйте is_resource($zip) после zip_open(), чтобы никогда не итерировать по сломанному дескриптору.
  • Движение только вперёд. Перемотки нет. Чтобы обработать архив повторно, откройте его заново с помощью zip_open().
  • Удалено в PHP 8. Эти функции были удалены в PHP 8.0. Код, который должен работать на современном PHP, следует переписать с использованием объектно-ориентированного класса ZipArchive.

Современная альтернатива: ZipArchive

В PHP 8 и более поздних версиях для обхода архива используйте класс ZipArchive. Он также предоставляет произвольный доступ по индексу, что невозможно с zip_read():

$zip = new ZipArchive();
if ($zip->open("example.zip") === true) {
    for ($i = 0; $i < $zip->numFiles; $i++) {
        $stat = $zip->statIndex($i);
        echo "Name: {$stat['name']}\n";
        echo "Compressed Size: {$stat['comp_size']}\n";
        echo "Uncompressed Size: {$stat['size']}\n";
    }
    $zip->close();
}

Смотрите обзор расширения PHP Zip для полного описания API ZipArchive.

Заключение

zip_read() перемещает однонаправленный курсор по записям zip-архива, открытого с помощью zip_open(), каждый раз возвращая ресурс записи и false в конце. Это основа устаревшего процедурного цикла чтения zip в паре с функциями zip_entry_* для проверки и извлечения каждой записи. Поскольку этот API был удалён в PHP 8.0, для кода, ориентированного на актуальные версии PHP, предпочтительно использовать ZipArchive.

Практика

Практика
Для чего используется функция zip_read() в PHP?
Для чего используется функция zip_read() в PHP?
Was this page helpful?