Web

Как заархивировать целую папку с помощью PHP

Я нашел несколько способов, как сделать ZIP для определенного файла, но как насчет определенной папки?

Folder/

  index.html

  picture.jpg

  important.txt

 Внутри папки My Folder находятся файлы. После архивации папки My Folder я также хочу удалить все содержимое папки, кроме important.txt.

Мне нужна ваша помощь. Спасибо.

 

Ответ 1

Архивация целой папки:

// Получаем реальный путь к нашей папке

$rootPath = realpath('folder-to-zip');

// Инициализация объекта архива

$zip = new ZipArchive();

$zip->open('file.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);

// Создание рекурсивного итератора каталогов

/** @var SplFileInfo[] $files */

$files = new RecursiveIteratorIterator(

    new RecursiveDirectoryIterator($rootPath),

    RecursiveIteratorIterator::LEAVES_ONLY

);

foreach ($files as $name => $file) {

    // Пропустите каталоги (они будут добавлены автоматически)

    if (!$file->isDir()) {

        // Получение реального и относительного пути для текущего файла

        $filePath = $file->getRealPath();

        $relativePath = substr($filePath, strlen($rootPath) + 1);

        // Добавить текущий файл в архив

        $zip->addFile($filePath, $relativePath);

    }

}

// Zip-архив будет создан только после закрытия объекта

$zip->close();

  Архивация папки + удаление всех файлов, кроме "important.txt":

// Инициализация объекта архива

$zip = new ZipArchive();

$zip->open('file.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);

// Инициализация пустого "списка удаления"

$filesToDelete = array();

// Создание рекурсивного итератора каталогов

/** @var SplFileInfo[] $files */

$files = new RecursiveIteratorIterator(

    new RecursiveDirectoryIterator($rootPath),

    RecursiveIteratorIterator::LEAVES_ONLY

);

foreach ($files as $name => $file) {

    // Пропустите каталоги (они будут добавлены автоматически)

    if (!$file->isDir()) {

        // Получение реального и относительного пути для текущего файла

        $filePath = $file->getRealPath();

        $relativePath = substr($filePath, strlen($rootPath) + 1);

        // Добавить текущий файл в архив

        $zip->addFile($filePath, $relativePath);

        // Добавить текущий файл в "список удаления"

        // удалить его позже, потому что ZipArchive создает архив только после вызова функции close, и ZipArchive блокирует файлы до создания архива

        if ($file->getFilename() != 'important.txt') {

            $filesToDelete[] = $filePath;

        }

    }

}

// Zip-архив будет создан только после закрытия объекта

$zip->close();

// Удалить все файлы из "списка удаления"

foreach ($filesToDelete as $file) {

    unlink($file);

}

 

Ответ 2

В классе ZipArchive есть полезный недокументированный метод: addGlob();

$zipFile = "./testZip.zip";

$zipArchive = new ZipArchive();

if ($zipArchive->open($zipFile, (ZipArchive::CREATE | ZipArchive::OVERWRITE)) !== true)

    die("Ошибка при создании архива\n");

$zipArchive->addGlob("./*.txt");

if ($zipArchive->status != ZIPARCHIVE::ER_OK)

    echo "Ошибка при записи файлов в zip\n";

$zipArchive->close();

 

Ответ 3

$zip = new ZipArchive;

$zip->open('myzip.zip', ZipArchive::CREATE);

foreach (glob("target_folder/*") as $file) {

    $zip->addFile($file);

    if ($file != 'target_folder/important.txt') unlink($file);

}

$zip->close();

Однако это не будет рекурсивно архивироваться.

 

Ответ 4

Я попробовал использовать приведенный ниже код, и он работает. Код не требует пояснений.

<?php

class FlxZipArchive extends ZipArchive {

 public function addDir($location, $name) {

       $this->addEmptyDir($name);

       $this->addDirDo($location, $name);

 } 

 private function addDirDo($location, $name) {

    $name .= '/';

    $location .= '/';

    $dir = opendir ($location);

    while ($file = readdir($dir)) {

 

        if ($file == '.' || $file == '..') continue;

        $do = (filetype( $location . $file) == 'dir') ? 'addDir' : 'addFile';

        $this->$do($location . $file, $name . $file);

    }

 } 

}

?>

 

<?php

$the_folder = '/path/to/folder/to/be/zipped';

$zip_file_name = '/path/to/zip/archive.zip';

$za = new FlxZipArchive;

$res = $za->open($zip_file_name, ZipArchive::CREATE);

if($res === TRUE) {

    $za->addDir($the_folder, basename($the_folder));

    $za->close();

}

else{

echo 'Не удалось создать zip архив!';

}

?>

 

Ответ 5

Это функция, которая архивирует всю папку и ее содержимое в zip-файл, и вы можете использовать ее просто, например, так :

addzip ("path/folder/" , "/path2/folder.zip" );

 И непосредственно реализация:

// сжать все файлы в исходном каталоге в каталог назначения 

    function create_zip($files = array(), $dest = '', $overwrite = false) {

    if (file_exists($dest) && !$overwrite) {

        return false;

    }

    if (($files)) {

        $zip = new ZipArchive();

        if ($zip->open($dest, $overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) {

            return false;

        }

        foreach ($files as $file) {

            $zip->addFile($file, $file);

        }

        $zip->close();

        return file_exists($dest);

    } else {

        return false;

    }

}

 

function addzip($source, $destination) {

    $files_to_zip = glob($source . '/*');

    create_zip($files_to_zip, $destination);

    echo "done";

}

 

 

Схожие статьи

Web

Как предотвратить SQL-инъекцию в PHP?

Web

PHP + curl, пример кода HTTP POST

Web

Как я могу хранить и извлекать изображения из базы данных MySQL с помощью PHP

Самый быстрый DNS-сервер России: сравниваем и выбираем лучший из них
Web

Самый быстрый DNS-сервер России: сравниваем и выбираем лучший из них