Technik, Gothic und Anderes

Technik ist Spiel, Gothic ist ernst und Zeit hat man zuviel

Zipdateien on-the-fly erstellen mit PHP

Geschrieben von skaldrom am 17. October 2007

Das Problem

On-The-Fly An unserer Schule wird Moodle als LMS (Learning Management System) verwendet. Es eignet sich sehr gut um Unterrichtsunterlagen wie Skripts, Aufträge und Präsentationen zu publizieren und den Lernenden auf eine angenehme Art und Weise zur Verfügung zu stellen. In einigen Kursen gibt es sehr viele dieser Ressourcen (Dateien und Verzeichnisse) zum Download und alleine schon das Anklicken und Speichern nimmt einen grossen Teil des zur Verfügung stehenden Zeitbudgets ein.

Einzelne Ressourcen können von der Lehrperson unsichtbar gemacht werden und nicht alle Dateien eines Kurses stehen zum Download bereit. Die Ansicht ist also sehr individuell und kann sich schnell ändern. Die Dateien werden über eine Versionsverwaltung in das System eingespiesen und können sich so ausserhalb des Systems verändern. Leider verunmöglicht dies die offensichtliche Lösung, einfach ein statisches Zip-Archiv zum Download zur Verfügung zu stellen.

Screenshot Moodle

Die Lösung

Das Zip muss also dynamisch (im Speicher) generiert werden bei einem Aufruf. Fündig wurde ich bei der Klasse archive bei phpclasses.org. Neben Zip-Archiven kann sie auch tar’s, gzip’s und bzip2’s erzeugen. Ich habe einige, kleine Erweiterungen vorgenommen, die noch beschrieben werden.

Die Handhabung ist sehr einfach:

// Archivklasse einbinden:
require_once ('lib/archive.php');

// Objekt erzeugen. Das Argument bezeichnet den Dateinamen
$zipfile= new zip_file('Meine Zipdatei.zip');

// Die Optionen
$zipfile->set_options(array (
        'basedir' => "/home/me/toZip/", // Das Basisverzeichnis. Sonst wird der ganze Pfad von / an im Zip gespeichert.
        'followlinks' => 1, // Symlinks sollen berücksichtigt werden
        'inmemory' => 1, // Die Datei nur im Speicher erstellen
        'level' => 6, // Level 1 = schnell, Level 9 = gut
        'recurse' => 1, // In Unterverzeichnisse wechseln
        // Wenn zu grosse dateien verarbeitet werden, kannes zu einem php memory error kommen
        // Man sollte nicht über das halbe memory_limit (php.ini) hinausgehen
        'maxsize' => 12*1024*1024 // Nur Dateien die <= 12 MB gross sind zippen
));

// Alle Dateien im Verzeichnis /home/me/toZip/Stuff hinzufügen
// Alle ".doc" Dateien und alle Ordner im Verzeichnis /home/me/toZip/Letters hinzufügen
$zipfile->add_files(array("Stuff", "Letters/*.doc"));

// Alle ".tmp" dateien in Stuff ausschliessen
$zipfile->exclude_files("htdocs/*.tmp");

// Alle Dateien in ".svn" und "CVS" Verzeichnissen ausschliessen (Regular Expressions)
$zipfile->exclude_regexp_files('.*/CVS|.*/CVS/.*|.*/\.svn|.*/\.svn.*');

// Archiv erstellen
$zipfile->create_archive();

// Archiv zum Download anbieten
$zipfile->download_file();

Änderungen

Ich habe folgende Dinge gegenüber der original archive.php geändert:

  • Mittels exclude_regexp_files() können Dateien auf Grund von Regular Expressions ausgeschlossen werden.
  • Die maxsize Option erlaubt das Ausschliessen von Dateien die grösser sind als die angegebene Zahl in Byte.
  • Verzeichnisse unter Linux werden als Verzeichnisse behandelt (Bug?)
  • exclude_file() prüft, ob eine Datei ausgeschlossen würde

Meine Version kann natürlich auch frei heruntergeladen werden.

Teile und geniesse:
  • Technorati
  • del.icio.us
  • MisterWong
  • Digg
  • StumbleUpon
  • blogmarks
  • Furl
  • Simpy
  • Spurl
  • YahooMyWeb

Ähnliche Artikel


9 Antworten zu “Zipdateien on-the-fly erstellen mit PHP”

Kommentare

  1. Marciel Schreibt:

    Hallo,

    habe das mal ausprobiert, bekomme aber kein Ergebnis. Wie genau muss ich das jetzt machen, wenn ich zum Beispiel den Ordner uploads/images komplett zippen will?

    Welche Dateien muss ich erstellen und mit welchen Scriptinhalt???

    Also ich habe bislang folgendes versucht:
    -Ordner lib erstellt und Datei archieves.php reingeladen
    -im basisverz. eine Datei zip.php mit dem obigen Script und meinen Einstellungen erstellt.

    Beim Aufruf ist wie gesasgt nichts passiert.

  2. admin Schreibt:

    Ich habe Dir gemailt und werde das Problem und die Lösung hier gerne posten…

  3. Marciel Schreibt:

    Vielen Dank für die schnelle Reaktion. Freu mich schon auf die Lösung.

  4. admin Schreibt:

    Oky, ich hoffe es hat funktioniert… Der Code in diesem Beitrag hatte Bugs (korrigiert) und es sollten keine nichtexistenten Verzeichnisse ausgeschlossen werden….

  5. Marciel Schreibt:

    Jetzt bleibt nur noch das Problem, dass der Microsoft IE es nicht schafft, den richtigen Dateinamen bzw. -pfad mitzubekommen und immer versucht die PHP-Datei herunterzuladen, anstatt der ZIP-Datei.

  6. hydrauligzap Schreibt:

    hallo,

    obwohl der artikel schon etwas älter ist hätte ich da noch ne frage.
    und zwar bringt er bei mir immer:
    Warning: Cannot modify header information - headers already sent by…
    an was könnte das denn liegen? an php 5? (ist mit zip-enabled compiliert.)
    ich hab auch keine ausgabe davor gemacht. nur comments im code, wie in deinem beispiel.
    hast du da ne idee?

  7. Marciel Schreibt:

    Kann man mit der Class auch ein ZIP-Archiv in ein Verzeichnis entpacken??
    Wie müsste der Code dafür aussehen??

    Mfg

  8. Carlos Schreibt:

    Hallo

    Ich habe die Klasse implementiert und es scheint soweit zu funktionieren. Das Problem ist nur, dass sich die Files im ZIP nicht öffnen lassen.

    Beim Öffnen des ZIP Files melden die ZIP Programme folgendes:
    WinRAR: “Unexpected end of archive”
    Microsoft ZIP: “Der ZIP-komprimierte Ordner ist ungültig oder beschädigt.

    Beim Versuch, ein jpg aus WinRar zu öffnen meldet dieser:
    Unexpected end of archive
    C:\TEMP\test\Meine Zipdatei.zip: Either multipart or corrupt ZIP archive

    An was könnte das liegen? Serverkonfiguration? Zur Info: Damit ich die Header Funktion innerhalb einer Klasse benutzen kann, habe ich in .htaccess php_flag output_buffering On.

    Für mögliche Hilfestellungen bin ich euch dankbar.

  9. skaldrom Schreibt:

    Was diese Klasse angeht habe ich noch einige Anfragen offen. Das Problem ist halt, ich komm so selten an Windows Compies :-(… Aber ich hab Dir gemailt…

Lassen Sie eine Antwort hier...

XHTML: Sie können folgende Tags verwenden: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>