Mittels "php" Verzeichnisse zippen

Hallo,

ich hoffe, jemand kann mir weiter helfen. Ich würde gern den Ordner Media mit allen Unterverzeichnissen zippen und als ganze zip Datei downloaden. Laut meinem Hoster ist das mit php möglich, leider hat der Service nicht geschrieben wie.

Ausprobiert habe ich folgende Variante -danke an den Ersteller!-, die aber jede Menge Ordner nicht in das Zip Archiv aufnimmt, allerdings nur lokal auf dem PC.

Meldung: media\image\03\4c…WARNUNG: Der Ordner wurde nicht ins Archiv übernommen.

Ein weiteres Problem ist die Größe. Es sind über 2 GB im Ordner Media, daher könnte es zu Memory Limit und max. execution time Fehlern kommen, auf dem Webspace bricht das Ganze dann auch zusammen.

Gbt es dafür eine Lösung?

open("media.zip", ZIPARCHIVE::CREATE) !== TRUE) {
    die ("Das Archiv konnte nicht erstellt werden!");
}
 
echo "";
// Gehe durch die Ordner und füge alles dem Archiv hinzu
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($folder));
foreach ($iterator as $key=>$value) {
 
  if(!is_dir($key)) { // wenn es kein ordner sondern eine datei ist
    // echo $key . " _ _ _ _Datei wurde übernommen";
    $zip->addFile(realpath($key), $key) or die ("FEHLER: Kann Datei nicht anfuegen: $key");
    $fc++;
 
  } elseif (count(scandir($key)) <= 2) { // der ordner ist bis auf . und .. leer
    // echo $key . " _ _ _ _Leerer Ordner wurde übernommen";
    $zip->addEmptyDir(substr($key, -1*strlen($key),strlen($key)-1));
    $dc++;
 
  } elseif (substr($key, -2)=="/.") { // ordner .
    $dc++; // nur für den bericht am ende
   
  } elseif (substr($key, -3)=="/.."){ // ordner ..
    // tue nichts
   
  } else { // zeige andere ausgelassene Ordner (sollte eigentlich nicht vorkommen)
    echo $key . "WARNUNG: Der Ordner wurde nicht ins Archiv übernommen.";
  }
}
echo "";
 
// speichert die Zip-Datei
$zip->close();
 
// bericht
echo "Das Archiv wurde erfolgreich erstellt.";
echo "Ordner: " . $dc . "";
echo "Dateien: " . $fc . "";
?>

Danke und Gruß

Die If-Abfrage ergibt keinen richtigen Sinn im Zusammenhang mit der Fehlermeldung. 

  • WENN kein Verzeichnis …
  • WENN Verzeichnis leer nicht selbst und drüber 
  • WENN Verzeichnis selbst
  • WENN Verzeichnis drüber
  • ANDERNFALLS ? Er findet also ein Verzeichnis und schreibt dahinter „Warnung“ ?

An der Stelle von ANDERFALLS müsste doch das hinzufügen zur Zip erfolgen? 

Sieht so aus, als würde es lokal auf dem PC funktionieren, trotz der Fehlermeldung sind die Unterordner mit Datei vorhanden. Bleibt das Problem auf dem Webspace. Kann man so zippen, dass z.B. nur ein Teil gepackt wird, also von Ordner Media/00 bis Media/c0 etc? So könnte das ganze etwas gestückelt werden, damit es überhaupt auf dem Server funktioniert.

 

Eventuell ist auch noch PHP mit exec eine Option - sofern dies der Hoster unterstützt. Dann könnte man auch TAR benutzen. Online würde es dann keine Rolle spielen wie groß die Ordner sind. Nur so eine Überlegung.

Hallo,

du kannst die Dot Files auch überspringen, wenn du dem FilesystemIterator Konstruktor die Option mitgibst:

$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($folder, \FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::SKIP_DOTS));

Außerdem gibt es auch eine is_file Funktion in PHP, dann würde deine Prüfung, ob es eine Date ist sinniger sein: http://php.net/manual/de/function.is-file.php

 

Generell würde ich das Skript nicht über den Webserver laufen lassen, weil du dann immer die max_execution_time hast. Wenn du das Skript direkt von der Kommandozeile aufrufst, dann gibt es schlicht keine max_execution_time. Außerdem empfehle ich gerade bei großen Verzeichnissen einen parallelen ZIP Algorithmus. Damit fällt PHP als ZIP Generator schonmal raus. Du könntest ein Shell Skript für 7-Zip oder pigz schreiben. Tar oder gzip fällt leider auch raus, weil die beiden Linux Standardkommandos auch nicht parallel arbeiten.

 

... or die('ging nicht');

würde ich auch nicht machen. Was brignt dir das abzubrechen, wenn eine Datei nicht gezippt werden konnte? Ist außerdem sehr alter Stil, keine Ahnung, woher du das noch hast…

 

 

MFG derwunner

1 Like

Hab ich im WWW gefunden  Wink  Ich kann so etwas nicht selbst schreiben. Das mit der Kommandozeile ist ein guter Tipp, das werde ich Mal ausprobieren.

Gruß