So komprimieren Sie einen ganzen Ordner mit PHP

Lesezeit: 9 Minuten

So komprimieren Sie einen ganzen Ordner mit PHP
wininana

Ich habe hier bei stackoveflow einige Codes gefunden, wie man eine bestimmte Datei zippen kann, aber wie wäre es mit einem bestimmten Ordner?

Folder/
  index.html
  picture.jpg
  important.txt

innen hinein My Folder, es gibt Dateien. nach dem zippen der My Folderich möchte auch den gesamten Inhalt des Ordners außer löschen important.txt.

Habe das hier bei Stack gefunden

Ich brauche deine Hilfe. Danke.

  • Soweit ich sehen kann, komprimiert der von Ihnen bereitgestellte Stackoverflow-Link tatsächlich mehrere Dateien. Mit welchem ​​Teil hast du Probleme?

    – Lasse Espeholt

    6. Februar 2011 um 17:04 Uhr

  • @lasseespeholt Der Link, den ich dir gegeben habe, komprimiert nur eine bestimmte Datei, nicht den Ordner und den Inhalt des Ordners.

    – wininana

    6. Februar 2011 um 17:05 Uhr

  • Er nimmt eine Reihe von Dateien (im Wesentlichen einen Ordner) und fügt alle Dateien der ZIP-Datei (der Schleife) hinzu. Ich kann sehen, dass jetzt eine gute Antwort gepostet wurde +1 🙂 das ist der gleiche Code, das Array ist jetzt nur eine Liste von Dateien aus einem Verzeichnis.

    – Lasse Espeholt

    6. Februar 2011 um 17:07 Uhr

  • mögliches Duplikat des Ordners compress/archive mit PHP-Skript

    – Pekka

    30. April 2011 um 14:25 Uhr

  • Dies kann Ihnen helfen encodingbin.com/compressing-a-directory-of-files-with-php

    – Manoj Dhiman

    21. September 2017 um 20:08 Uhr

So komprimieren Sie einen ganzen Ordner mit PHP
Vater

Code aktualisiert am 22.04.2015.

Zippen Sie einen ganzen Ordner:

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

Einen ganzen Ordner komprimieren + alle Dateien außer “important.txt” löschen:

// 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);
}

  • Sie müssen chmod (beschreibbar) im Verzeichnis (wo sich dieses Skript befindet) auf 777 setzen. Beispiel: Wenn sich das Skript in /var/www/localhost/script.php befindet, müssen Sie chmod 0777 im Verzeichnis /var/www/localhost festlegen /.

    – Papa

    6. Februar 2011 um 18:50 Uhr


  • Löschen der Dateien vor dem Anruf $zip->close() wird nicht funktionieren. Überprüfen Sie meine Antwort hier

    – hek2mgl

    3. Februar 2014 um 13:45 Uhr


  • @alnassre das ist Voraussetzung aus der Frage: “Ich möchte auch den gesamten Inhalt des Ordners außer important.txt löschen”. Außerdem rate ich Ihnen, Code immer zu lesen, bevor Sie ihn ausführen.

    – Papa

    21. April 2015 um 23:12 Uhr

  • @alnassre hahahaha … sorry 🙂 … hahaha

    – Ondrej Rafaj

    25. Mai 2015 um 19:54 Uhr

  • @nick-newman, ja, um den Prozentsatz zu berechnen, den Sie verwenden können php.net/manual/ru/function.iterator-count.php + Zähler innerhalb der Schleife. In Bezug auf die Komprimierungsstufe ist dies mit ZipArchive derzeit nicht möglich: stackoverflow.com/questions/1833168/…

    – Vater

    20. Dezember 2015 um 12:07 Uhr

1646928849 27 So komprimieren Sie einen ganzen Ordner mit PHP
Markus Bäcker

Es gibt eine nützliche undokumentierte Methode in der ZipArchive-Klasse: addGlob();

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

if ($zipArchive->open($zipFile, (ZipArchive::CREATE | ZipArchive::OVERWRITE)) !== true)
    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();

Jetzt dokumentiert unter: www.php.net/manual/en/ziparchive.addglob.php

  • @netcoder – die Vorteile, das PHPT zum Testen geschrieben zu haben … im Grunde die Quelle für die ZipArchive-Klasse durchlesen und dort finden …. es gibt auch eine undokumentierte addPattern() -Methode, die ein Muster im Regexp-Stil verwendet, aber ich habe es nie geschafft, das zum Laufen zu bringen (kann ein Fehler in der Klasse sein)

    – Markus Bäcker

    6. Februar 2011 um 17:32 Uhr

  • @kread – Sie können dies mit jeder Dateiliste verwenden, die mit glob() extrahiert werden kann, daher finde ich es äußerst nützlich, seit ich es entdeckt habe.

    – Markus Bäcker

    6. Februar 2011 um 19:16 Uhr

  • Ist addGlob rekursiv?

    – Vincent Poirier

    28. Januar 2016 um 16:50 Uhr

  • ZipArchive::open() gibt bei einem Fehler eine Ganzzahl ungleich Null zurück, also wird geprüft if (!$zipArchive->open($zipFile, ZIPARCHIVE::OVERWRITE)) ist ungültig und hat gerade eine Stunde meiner Zeit beim Debuggen gekostet! Habe die Antwort entsprechend bearbeitet.

    – John Rix

    28. Februar 2020 um 10:24 Uhr


  • Auch mit nur ZipArchive::OVERWRITE schlägt fehl, wenn die benannte Datei nicht vorhanden ist, verwenden Sie also (ZipArchive::CREATE | ZipArchive::OVERWRITE) stattdessen (vorausgesetzt, Sie möchten ggf. erstellen oder überschreiben).

    – John Rix

    28. Februar 2020 um 10:31 Uhr

Versuche dies:

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

Dies wird nicht zip aber rekursiv.

  • Es löscht sicher einige Dateien in My folderaber ich habe auch einen Ordner in einem Ordner My folder was mir einen Fehler gibt von: Permission denied by unlinking the folder with in My folder

    – wininana

    6. Februar 2011 um 17:13 Uhr


  • @Stupefy: Versuchen Sie es if (!is_dir($file) && $file != 'target_folder...') stattdessen. Oder überprüfen Sie die @kread-Antwort, wenn Sie rekursiv komprimieren möchten, dies ist der effizienteste Weg.

    – Netcoder

    6. Februar 2011 um 17:21 Uhr

  • Der Ordner innerhalb der My folder ist immer noch nicht gelöscht, aber es gibt sowieso keine Fehler mehr.

    – wininana

    6. Februar 2011 um 17:33 Uhr

  • Ich habe auch vergessen zu erwähnen, dass keine ZIP-Dateien erstellt werden.

    – wininana

    6. Februar 2011 um 17:36 Uhr

  • Löschen der Dateien vor dem Anruf $zip->close() wird nicht funktionieren. Überprüfen Sie meine Antwort hier

    – hek2mgl

    3. Februar 2014 um 13:48 Uhr

Ich gehe davon aus, dass dies auf einem Server ausgeführt wird, auf dem sich die ZIP-Anwendung im Suchpfad befindet. Sollte für alle Unix-basierten und ich denke, die meisten Windows-basierten Server gelten.

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

Das Archiv befindet sich danach in archive.zip. Denken Sie daran, dass Leerzeichen in Datei- oder Ordnernamen eine häufige Ursache für Fehler sind und nach Möglichkeit vermieden werden sollten.

Ich habe es mit dem folgenden Code versucht und es funktioniert. Der Code ist selbsterklärend, bei Fragen bitte melden.

<?php
class FlxZipArchive extends ZipArchive 
{
 public function addDir($location, $name) 
 {
       $this->addEmptyDir($name);
       $this->addDirDo($location, $name);
 } 
 private function addDirDo($location, $name) 
 {
    $name .= "https://stackoverflow.com/";
    $location .= "https://stackoverflow.com/";
    $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';
}
?>

  • Hervorragende Lösung. Es funktioniert auch in Laravel 5.5. das hat mir sehr gut gefallen. (y)

    – Webkünstler

    29. November 2017 um 6:46 Uhr

  • Toller Code! Sauber, einfach und perfekt funktionierend! 😉 Es scheint mir die beste Antwort zu sein. Falls es jemandem helfen kann: Habe ich gerade hinzugefügt ini_set('memory_limit', '512M'); vor der Ausführung des Skripts und ini_restore('memory_limit'); Am Ende. Es war notwendig, bei großen Ordnern (es war ein Ordner größer als 500 MB) Speichermangel zu vermeiden.

    – Jacopo Pace

    1. Dezember 2017 um 16:38 Uhr

  • In meiner Umgebung (PHP 7.3, Debian) wurde ein ZIP-Archiv ohne Verzeichnisverzeichnis erstellt (große, leere Datei). Ich musste die folgende Zeile ändern: $name .= ‘/’; in $name = ($name == ‘.’ ? ” : $name .’/’);

    – Gerfried

    13. August 2019 um 9:17 Uhr

  • Das funktioniert für mich. Danke für das Teilen. Prost!

    – Sathiska

    3. Januar 2020 um 11:00 Uhr

Dies ist eine Funktion, die einen ganzen Ordner und seinen Inhalt in eine Zip-Datei komprimiert, und Sie können sie einfach so verwenden:

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

Funktion:

// 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";
}

  • Hervorragende Lösung. Es funktioniert auch in Laravel 5.5. das hat mir sehr gut gefallen. (y)

    – Webkünstler

    29. November 2017 um 6:46 Uhr

  • Toller Code! Sauber, einfach und perfekt funktionierend! 😉 Es scheint mir die beste Antwort zu sein. Falls es jemandem helfen kann: Habe ich gerade hinzugefügt ini_set('memory_limit', '512M'); vor der Ausführung des Skripts und ini_restore('memory_limit'); Am Ende. Es war notwendig, bei großen Ordnern (es war ein Ordner größer als 500 MB) Speichermangel zu vermeiden.

    – Jacopo Pace

    1. Dezember 2017 um 16:38 Uhr

  • In meiner Umgebung (PHP 7.3, Debian) wurde ein ZIP-Archiv ohne Verzeichnisverzeichnis erstellt (große, leere Datei). Ich musste die folgende Zeile ändern: $name .= ‘/’; in $name = ($name == ‘.’ ? ” : $name .’/’);

    – Gerfried

    13. August 2019 um 9:17 Uhr

  • Das funktioniert für mich. Danke für das Teilen. Prost!

    – Sathiska

    3. Januar 2020 um 11:00 Uhr

1646928849 660 So komprimieren Sie einen ganzen Ordner mit PHP
Waqar Alamgir

Verwenden Sie diese Funktion:

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('\\', "https://stackoverflow.com/", realpath($source));

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

        foreach ($files as $file) {
            $file = str_replace('\\', "https://stackoverflow.com/", $file);

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

            $file = realpath($file);

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

    return $zip->close();
}

Beispielanwendung:

zip('/folder/to/compress/', './compressed.zip');

988410cookie-checkSo komprimieren Sie einen ganzen Ordner mit PHP

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy