Введение в работу с ZIP-архивами в PHP
ZIP-архивы остаются одним из самых популярных форматов сжатия данных в веб-разработке. В PHP работа с ними реализована нативно через расширение Zip, которое предоставляет мощный класс ZipArchive. Это позволяет разработчикам легко создавать, читать, обновлять и извлекать файлы из архивов без установки дополнительных сторонних библиотек.
На образовательном портале PythonLib.ru мы разберём все аспекты работы с ZIP в PHP: от базовых операций до продвинутых техник, включая сжатие с паролем, обработку больших объёмов данных и интеграцию с буферизацией вывода.
Установка и проверка расширения Zip
Класс ZipArchive доступен в PHP начиная с версии 5.2.0. Для его использования необходимо убедиться, что расширение zip включено в конфигурации сервера. Проверить это можно с помощью функции phpinfo() или простым скриптом:
<?php
if (class_exists('ZipArchive')) {
echo "Расширение Zip доступно";
} else {
echo "Расширение Zip не установлено";
}
?>
В большинстве современных хостингов расширение уже предустановлено. Если его нет — обратитесь к администратору сервера или выполните установку через пакетный менеджер (например, apt-get install php-zip для Debian/Ubuntu).
Основные операции с ZipArchive
1. Создание нового ZIP-архива
Для создания архива используется метод open() с флагом ZipArchive::CREATE. Рассмотрим базовый пример:
<?php
$zip = new ZipArchive();
$filename = 'example.zip';
if ($zip->open($filename, ZipArchive::CREATE) === TRUE) {
// Добавление файла из строки
$zip->addFromString('hello.txt', 'Привет, мир!');
// Добавление существующего файла
$zip->addFile('/path/to/image.jpg', 'images/photo.jpg');
// Добавление пустой директории
$zip->addEmptyDir('documents');
$zip->close();
echo "Архив создан успешно";
} else {
echo "Ошибка создания архива";
}
?>
Обратите внимание: второй параметр addFile() задаёт путь внутри архива, что позволяет организовать структуру папок.
2. Распаковка ZIP-архива
Для извлечения всех файлов используется метод extractTo():
<?php
$zip = new ZipArchive();
if ($zip->open('example.zip') === TRUE) {
$zip->extractTo('/destination/folder/');
$zip->close();
echo "Архив распакован";
} else {
echo "Не удалось открыть архив";
}
?>
Также можно извлечь только конкретный файл, указав его внутренний путь вторым аргументом:
$zip->extractTo('/destination/', 'images/photo.jpg');
3. Чтение содержимого архива без распаковки
Иногда требуется только просмотреть список файлов внутри архива:
<?php
$zip = new ZipArchive();
if ($zip->open('archive.zip') === TRUE) {
for ($i = 0; $i < $zip->numFiles; $i++) {
$stat = $zip->statIndex($i);
echo "Файл: " . $stat['name'] . " (размер: " . $stat['size'] . " байт)\n";
}
$zip->close();
}
?>
Метод statIndex() возвращает массив с информацией: имя, размер, дата модификации, CRC32 и другие метаданные.
Продвинутые возможности
Сжатие с паролем (PHP 7.2+)
Начиная с PHP 7.2, ZipArchive поддерживает шифрование с паролем через алгоритм AES-256:
<?php
$zip = new ZipArchive();
if ($zip->open('protected.zip', ZipArchive::CREATE) === TRUE) {
$zip->setPassword('supersecret');
$zip->addFile('document.pdf');
// Включаем шифрование для последнего добавленного файла
$zip->setEncryptionName('document.pdf', ZipArchive::EM_AES_256);
$zip->close();
echo "Зашифрованный архив создан";
}
?>
Сжатие с сохранением структуры каталогов
Для рекурсивного добавления всех файлов из папки можно написать вспомогательную функцию:
<?php
function addFolderToZip($zip, $folder, $parentPath = '') {
$files = new RecursiveIteratorIterator(
new Recursive