Как сжать всю папку с помощью PHP - PullRequest
109 голосов
/ 06 февраля 2011

Я нашел здесь в stackoveflow несколько кодов о том, как архивировать определенный файл, но как насчет конкретной папки?

Folder/
  index.html
  picture.jpg
  important.txt

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

Нашел это здесь стек

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

Ответы [ 14 ]

275 голосов
/ 06 февраля 2011

Код обновлен 2015/04 / 22.

Zip целую папку:

// Get real path for our folder
$rootPath = realpath('folder-to-zip');

// Initialize archive object
$zip = new ZipArchive();
$zip->open('file.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);

// Create recursive directory iterator
/** @var SplFileInfo[] $files */
$files = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($rootPath),
    RecursiveIteratorIterator::LEAVES_ONLY
);

foreach ($files as $name => $file)
{
    // Skip directories (they would be added automatically)
    if (!$file->isDir())
    {
        // Get real and relative path for current file
        $filePath = $file->getRealPath();
        $relativePath = substr($filePath, strlen($rootPath) + 1);

        // Add current file to archive
        $zip->addFile($filePath, $relativePath);
    }
}

// Zip archive will be created only after closing object
$zip->close();

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

// Get real path for our folder
$rootPath = realpath('folder-to-zip');

// Initialize archive object
$zip = new ZipArchive();
$zip->open('file.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);

// Initialize empty "delete list"
$filesToDelete = array();

// Create recursive directory iterator
/** @var SplFileInfo[] $files */
$files = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($rootPath),
    RecursiveIteratorIterator::LEAVES_ONLY
);

foreach ($files as $name => $file)
{
    // Skip directories (they would be added automatically)
    if (!$file->isDir())
    {
        // Get real and relative path for current file
        $filePath = $file->getRealPath();
        $relativePath = substr($filePath, strlen($rootPath) + 1);

        // Add current file to archive
        $zip->addFile($filePath, $relativePath);

        // Add current file to "delete list"
        // delete it later cause ZipArchive create archive only after calling close function and ZipArchive lock files until archive created)
        if ($file->getFilename() != 'important.txt')
        {
            $filesToDelete[] = $filePath;
        }
    }
}

// Zip archive will be created only after closing object
$zip->close();

// Delete all files from "delete list"
foreach ($filesToDelete as $file)
{
    unlink($file);
}
48 голосов
/ 06 февраля 2011

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

$zipFile = "./testZip.zip";
$zipArchive = new ZipArchive();

if (!$zipArchive->open($zipFile, ZIPARCHIVE::OVERWRITE))
    die("Failed to create archive\n");

$zipArchive->addGlob("./*.txt");
if (!$zipArchive->status == ZIPARCHIVE::ER_OK)
    echo "Failed to write files to zip\n";

$zipArchive->close();

Теперь задокументировано по адресу: www.php.net / manual / en / ziparchive.addglob.php

19 голосов
/ 06 февраля 2011

Попробуйте это:

$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();

Это не будет рекурсивным, хотя.

16 голосов
/ 06 февраля 2011

Я предполагаю, что это выполняется на сервере, где zip-приложение находится в пути поиска. Должно быть верно для всех Unix-систем, и я думаю, что большинство Windows-серверов.

exec('zip -r archive.zip "My folder"');
unlink('My\ folder/index.html');
unlink('My\ folder/picture.jpg');

Архив будет постоянно находиться в файле archive.zip. Имейте в виду, что пропуски в именах файлов или папок являются частой причиной ошибок, и их следует по возможности избегать.

11 голосов
/ 04 декабря 2014

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

<?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 'Could not create a zip archive';
}
?>
7 голосов
/ 27 октября 2013

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

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

функция:

// compress all files in the source directory to destination directory 
    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";
}
1 голос
/ 23 февраля 2018

Используйте это работает нормально.

$dir = '/Folder/';
$zip = new ZipArchive();
$res = $zip->open(trim($dir, "/") . '.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);
if ($res === TRUE) {
    foreach (glob($dir . '*') as $file) {
        $zip->addFile($file, basename($file));
    }
    $zip->close();
} else {
    echo 'Failed to create to zip. Error: ' . $res;
}
1 голос
/ 31 января 2017

Используйте эту функцию:

function zip($source, $destination)
{
    if (!extension_loaded('zip') || !file_exists($source)) {
        return false;
    }

    $zip = new ZipArchive();
    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
    }

    $source = str_replace('\\', '/', realpath($source));

    if (is_dir($source) === true) {
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

        foreach ($files as $file) {
            $file = str_replace('\\', '/', $file);

            // Ignore "." and ".." folders
            if (in_array(substr($file, strrpos($file, '/')+1), array('.', '..'))) {
                continue;
            }               

            $file = realpath($file);

            if (is_dir($file) === true) {
                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
            } elseif (is_file($file) === true) {
                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    } elseif (is_file($source) === true) {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}

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

zip('/folder/to/compress/', './compressed.zip');
1 голос
/ 10 мая 2013

Это рабочий пример создания ZIP в PHP:

$zip = new ZipArchive();
$zip_name = time().".zip"; // Zip name
$zip->open($zip_name,  ZipArchive::CREATE);
foreach ($files as $file) {
  echo $path = "uploadpdf/".$file;
  if(file_exists($path)){
  $zip->addFromString(basename($path),  file_get_contents($path));---This is main function  
  }
  else{
   echo"file does not exist";
  }
}
$zip->close();
1 голос
/ 31 марта 2013

Почему бы не попробовать EFS PhP-ZiP MultiVolume Script ... Я архивировал и переносил сотни гигов и миллионы файлов ... ssh необходим для эффективного создания архивов.

Но я верю, что полученные файлы можно использовать с exec напрямую с php:

exec('zip -r backup-2013-03-30_0 . -i@backup-2013-03-30_0.txt');

Я не знаю, работает ли это. Я не пробовал ...

«секрет» заключается в том, что время выполнения для архивирования не должно превышать время, отведенное для выполнения кода PHP.

...