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

Использование zip_entry_compressedsize для работы со сжатыми ZIP файлами в PHP
Раздел: Архивация
zip_entry_compressedsize(resource zip_entry): int
Описание функции zip_entry_compressedsize

Функция zip_entry_compressedsize возвращает сжатый размер элемента внутри ZIP-архива, с которым работает указанный дескриптор записи.

Ее применяют, когда требуется узнать размер файла в архиве после сжатия, не извлекая его содержимое. Это полезно для анализа эффективности сжатия, проверки наличия достаточного места на диске перед распаковкой или отображения информации об архиве.

Функция является частью старого модуля Zip (до появления ZipArchive) и работает с ресурсом дескриптора записи, полученным с помощью zip_read() и zip_entry_open().

Аргументы функции

Функция принимает один обязательный параметр:

  • zip_entry (ресурс) - дескриптор записи ZIP-архива, полученный с помощью функции zip_entry_open.

Функция возвращает сжатый размер элемента в байтах в случае успеха или false в случае возникновения ошибки.

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

Простой пример чтения архива и получения сжатых размеров файлов:

<?php
$zip = zip_open('archive.zip');
if (is_resource($zip)) {
    while ($entry = zip_read($zip)) {
        $name = zip_entry_name($entry);
        $compressed_size = zip_entry_compressedsize($entry);
        echo "Файл: $name, Сжатый размер: $compressed_size байт\n";
    }
    zip_close($zip);
} else {
    echo "Не удалось открыть архив";
}
?>
Файл: document.txt, Сжатый размер: 1024 байт
Файл: image.jpg, Сжатый размер: 2048 байт

Пример с проверкой успешного открытия записи:

<?php
$zip = zip_open('archive.zip');
if ($zip) {
    $entry = zip_read($zip);
    if (zip_entry_open($zip, $entry, 'r')) {
        $size = zip_entry_compressedsize($entry);
        echo "Сжатый размер: $size байт";
        zip_entry_close($entry);
    }
    zip_close($zip);
}
?>
Сжатый размер: 1024 байт
Похожие функции в PHP

В современном PHP предпочтительнее использовать объектно-ориентированный класс ZipArchive, который появился в PHP 5.2.0.

ZipArchive::statIndex() - возвращает статистическую информацию о элементе архива по его индексу, включая сжатый размер в поле 'comp_size'.

<?php
$zip = new ZipArchive;
if ($zip->open('archive.zip') === TRUE) {
    $stat = $zip->statIndex(0);
    echo "Сжатый размер: " . $stat['comp_size'] . " байт";
    $zip->close();
}
?>

zip_entry_filesize() - возвращает оригинальный (несжатый) размер элемента ZIP-архива. Эта функция работает в паре с zip_entry_compressedsize для расчета степени сжатия.

Класс ZipArchive рекомендуется для новых проектов из-за более удобного API, лучшей обработки ошибок и активной поддержки. Старые функции типа zip_entry_compressedsize остаются для обратной совместимости.

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

Zip entry compressedsize в Python

Модуль zipfile предоставляет атрибут compress_size у объектов ZipInfo:

import zipfile
with zipfile.ZipFile('archive.zip', 'r') as zf:
    for info in zf.infolist():
        print(f"Файл: {info.filename}, Сжатый размер: {info.compress_size} байт")
Файл: document.txt, Сжатый размер: 1024 байт
Файл: image.jpg, Сжатый размер: 2048 байт
JavaScript (Node.js)

Модуль adm-zip позволяет получить сжатый размер через entry.header.compressedSize:

const AdmZip = require('adm-zip');
const zip = new AdmZip('archive.zip');
const entries = zip.getEntries();
entries.forEach(entry => {
    console.log(`Файл: ${entry.entryName}, Сжатый размер: ${entry.header.compressedSize} байт`);
});

Zip entry compressedsize в Java

В Java используют метод getCompressedSize() класса ZipEntry:

import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.Enumeration;

ZipFile zipFile = new ZipFile("archive.zip");
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
    ZipEntry entry = entries.nextElement();
    System.out.println("Файл: " + entry.getName() + 
                       ", Сжатый размер: " + entry.getCompressedSize() + " байт");
}
zipFile.close();

Основное отличие PHP функции от аналогов в других языках - использование ресурса вместо объектов, что характерно для старого процедурного подхода в PHP.

Типичные ошибки

Наиболее частая ошибка - передача некорректного или уже закрытого дескриптора записи:

<?php
$zip = zip_open('archive.zip');
$entry = zip_read($zip);
zip_entry_close($entry);
// Попытка использовать закрытый дескриптор
$size = zip_entry_compressedsize($entry);
var_dump($size);
?>
bool(false)

Ошибка при передаче дескриптора архива вместо дескриптора записи:

<?php
$zip = zip_open('archive.zip');
// Неверно: передается дескриптор архива, а не записи
$size = zip_entry_compressedsize($zip);
var_dump($size);
zip_close($zip);
?>
bool(false)

Попытка использовать функцию без предварительного открытия записи:

<?php
$zip = zip_open('archive.zip');
$entry = zip_read($zip);
// Запись не открыта через zip_entry_open
$size = zip_entry_compressedsize($entry);
var_dump($size);
zip_close($zip);
?>
bool(false)

Для избежания ошибок необходимо проверять тип ресурса и состояние дескриптора перед использованием функции.

Изменения в версиях PHP

Функция zip_entry_compressedsize была частью модуля Zip с момента его появления в PHP 4.1.0.

В PHP 8.0.0 модуль Zip (функции с префиксом zip_) был перемещен в PECL-расширение. По умолчанию он больше не входит в стандартную поставку PHP. Для его использования необходимо установить расширение через PECL: pecl install zip.

Это изменение связано с переходом на более современный API класса ZipArchive. Старые процедурные функции устарели, но сохраняются для обратной совместимости в PECL-расширении.

При использовании PHP 8 и выше рекомендуется мигрировать код на использование класса ZipArchive вместо процедурных функций для работы с ZIP-архивами.

Расширенные примеры использования
Расчет степени сжатия для каждого файла
Пример php
<?php
function calculateCompressionRatio($zip_filename) {
    $zip = zip_open($zip_filename);
    if (!is_resource($zip)) return false;
    
    $results = [];
    while ($entry = zip_read($zip)) {
        if (zip_entry_open($zip, $entry, 'r')) {
            $name = zip_entry_name($entry);
            $compressed = zip_entry_compressedsize($entry);
            $original = zip_entry_filesize($entry);
            
            $ratio = ($original > 0) ? (100 - ($compressed / $original * 100)) : 0;
            
            $results[$name] = [
                'compressed' => $compressed,
                'original' => $original,
                'ratio' => round($ratio, 2)
            ];
            
            zip_entry_close($entry);
        }
    }
    zip_close($zip);
    return $results;
}

$stats = calculateCompressionRatio('archive.zip');
foreach ($stats as $filename => $data) {
    echo "{$filename}: {$data['compressed']}/{$data['original']} байт ";
    echo "(сжатие: {$data['ratio']}%)\n";
}
?>
document.txt: 1024/2048 байт (сжатие: 50.00%)
image.jpg: 2048/2050 байт (сжатие: 0.10%)
Фильтрация файлов по размеру
Пример php
<?php
function findLargeCompressedFiles($zip_filename, $threshold) {
    $zip = zip_open($zip_filename);
    $large_files = [];
    
    if (is_resource($zip)) {
        while ($entry = zip_read($zip)) {
            if (zip_entry_open($zip, $entry, 'r')) {
                $name = zip_entry_name($entry);
                $size = zip_entry_compressedsize($entry);
                
                if ($size > $threshold) {
                    $large_files[] = [
                        'name' => $name,
                        'size' => $size
                    ];
                }
                zip_entry_close($entry);
            }
        }
        zip_close($zip);
    }
    return $large_files;
}

$large = findLargeCompressedFiles('archive.zip', 1500);
foreach ($large as $file) {
    echo "Крупный файл: {$file['name']} ({$file['size']} байт)\n";
}
?>
Крупный файл: image.jpg (2048 байт)
Обработка вложенных архивов
Пример php
<?php
function analyzeZipContents($zip_filename) {
    $zip = zip_open($zip_filename);
    $total_compressed = 0;
    $file_count = 0;
    
    if (is_resource($zip)) {
        while ($entry = zip_read($zip)) {
            if (zip_entry_open($zip, $entry, 'r')) {
                $name = zip_entry_name($entry);
                
                // Проверяем, не является ли файл вложенным архивом по расширению
                if (preg_match('/\.zip$/i', $name)) {
                    echo "Найден вложенный архив: $name\n";
                    // Для реального анализа потребовалась бы временная распаковка
                } else {
                    $size = zip_entry_compressedsize($entry);
                    $total_compressed += $size;
                    $file_count++;
                }
                
                zip_entry_close($entry);
            }
        }
        zip_close($zip);
    }
    
    return [
        'total_compressed' => $total_compressed,
        'file_count' => $file_count,
        'average_size' => ($file_count > 0) ? $total_compressed / $file_count : 0
    ];
}

$analysis = analyzeZipContents('archive.zip');
print_r($analysis);
?>
Найден вложенный архив: nested.zip
Array
(
    [total_compressed] => 3072
    [file_count] => 2
    [average_size] => 1536
)

PHP zip_entry_compressedsize function comments

En
Zip entry compressedsize Retrieve the compressed size of a directory entry