ZIP-Archive @ PHP

Komprimieren und expandieren von Verzeichnissen & Dateien

Archive sind Dateien, in denen andere Dateien und Verzeichnisse enthalten sind, meist in komprimierter Form.
Archiv-Dateien lassen sich in genau identischer Form (verlustfrei) wieder auspacken.
Archive werden wegen der einfachen Handhabung und dem geringen Speicher-Bedarf u.a. zum Speichern und Versenden von Daten verwendet.
Es gibt zahlreiche verschiedene Archiv-Formate.
Jeder PC sollte Software zur Handhabung der gängigsten Archive enthalten - (gzip, jar, tar, zip, ..) Programme dazu sind im Internet kostenfrei erhältlich.
OpenDocumentist ein offener Standard (kostenlos, lizenzfrei) zum Speichern von Büro-Dokumenten.
Jede OpenDocument Datei *.odt ist ein ZIP-komprimiertes Archiv, in dem → XML-Dateien enthalten sind.
XML ist ebenfalls ein offener Standard. Die XML-Dateien enthalten alle Daten (Struktur, Inhalt, Formatierung, ..) des Büro-Dokuments. Da XML aus 'reinem Text' besteht, sind diese Dateien mit jedem Text-Editor und mit Programmen jeder Programmiersprache zu bearbeiten.
Der OpenDocument Standard bietet für AnwenderInnen zahlreiche Vorteile gegenüber firmen-eigener binärer Codierung (z.B. des IT-Marktführers).
Gleichzeitig mit der Bedeutung von OpenDocument steigt daher die Bedeutung von Methoden zum Komprimieren und Expandieren von ZIP-Archiven.
PHP PHP Hypertext Processor
Modul ZIP Information zum PHP-Modul ZIP
ZipArchive Objekte vom Typ ZipArchive
Elemente Zugriff auf Verzeichnisse und Dateien in einem Zip-Objekt
Datenstrom Lesen einer Datei aus dem Archiv
OpenDocument Verarbeitung von OpenDocument Dateien
PCLZip PCLZIP & InfoZip: Win-Konsolen-Programme für ZIP-Archive
Verwandte Themen XML
Links Ausgewählte Links zum Thema 'ZIP @ PHP'

Modul ZIP

Erst ab Version >5.1 bietet PHP ein ausgereiftes Modul mit ZIP-Funktionen. Wenn sie noch PHP Version 4 verwenden, dann sollten sie das zum Anlass für die Installation einer aktuellen PHP Version nehmen. Das Modul kann auch mit älteren Versionen verwendet werden. Das erfordert jedoch einige Fachkenntnisse und kommt für Amateure nicht in Frage.

Windows

In den aktuellen Windows-Versionen ist das Modul php_zip.dll bei den Standard-Modulen enthalten, d.h. im PHP Sub-Verzeichnis ext
Die Verwendung des Moduls muss normalerweise ausdrücklich konfiguriert werden (rechts).
Nach der Konfiguration wird der Webserver neu gestartet.
Testen sie Verfügbarkeit des Moduls, z.B. mit Funktion phpinfo (→ Details).

Konfiguration
Die Datei php.ini (→ Details) steuert die Konfiguration.
Das Modul-Verzeichnis wird durch die Variable extension_dir der Konfiguration bezeichnet. Dorthin wird die Modul-Datei kopiert. Wenn die Variable leer ist, wird die Datei in das PHP-Verzeichnis kopiert (wo sich php.exe befindet).
Das Modul muss im Kapitel Dynamic Extensions der Konfiguration eingetragen oder aktiviert werden:
extension=php_zip.dll

Linux

Das Modul ist je nach Distribution enthalten.
Im einfachsten Fall wird das Modul mit dem Software Installer (Auf SuSE mit YAST) installiert.
Wenn das nicht möglich ist, sucht man im Web des Distributors nach einer Möglichkeit, das Modul zu installieren.
Wenn auch das nicht möglich ist (leider derzeit bei den meisten SuSE-Versionen), dann muss man das Modul zip.so selbst herstellen (compilieren).

Details zum Compilieren von PHP-Modulen auf Linux

Compilieren des PHP-Moduls (→ Details)
Besorgen sie sich aus dem Internet (PHP, PECL) den Quelltext (source) des Moduls.
Lesen sie unbedingt die mitgelieferten Hinweise !
Entpacken sie das Archiv
Sie brauchen das Programm phpize
Auf SuSE müssen sie dazu mit YAST das Software-Paket php-devel installieren !
Compilieren sie das Modul.
Ergänzen sie die PHP-Konfiguration.

Kontrolle der Installation

Jedes Programm, welches ein PHP-Modul verwendet, sollte vor Beginn testen, ob das Modul verfügbar ist.

Test: Ist das Modul ZIP geladen ?
$zip_ok = 0;
if(extension_loaded('zip')) {$zip_ok=1;}
Live-Ergebnis: $zip_ok = 1

Objekt ZipArchive

Alle Arbeiten verwenden Objekte vom Typ ZipArchive
Im Beispiel liegt das ZIP-Archiv test.zip in einem Unterverzeichnis sub jenes Verzeichnisses, in welchem sich das PHP Programm befindet.
Alle Beispiele dieser Seite setzen voraus, dass ein ZipArchive Objekt $za erzeugt und erfolgreich geöffnet wurde.
$za = new ZipArchive();
$path = 'sub/test.zip';
$za->open($path);
Während der Entwicklung und zum Debuggen kann man zur Ausgabe der Eigenschaften die Funktionen print_r und var_dump (mit Variablen-Typ) verwenden. Sie geben in spartanischer Form Auskunft über das Objekt, z.B. Anzahl der enthaltenen Dateien:
['numFiles']=> int(123)
if($za) {
print_r($za);
var_dump($za);
}
else {print "Fehlermeldung";}
Das Beispiel rechts zeigt den Zugang zu einzelnen ausgewählten Eigenschaften eines ZipArchive Objekts.
$anz_dataien = $za->numFiles;
$status = $za->status;
$statusSys = $za->statusSys;
$name = $za->filename;
$comment = $za->comment;
Nach dem Ende aller Arbeiten wird das ZipArchive Objekt geschlossen.
zip_close($za);

Elemente des Zip-Objekts - Verzeichnisse und Dateien

Dieses Kapitel zeigt, wie man in einer Schleife alle in einem ZIP-Archiv enthaltenen Verzeichnisse und Dateien durchlaufen kann.
Als Beispiel wird eine Tabelle der wichtigsten Eigenschaften jedes Elements erzeugt.
Rechts der HTML-Quelltext zur Erzeugung der Tabelle und Überschrifts-Zeile.
HTML-Quelltext: Tabelle (Inhaltsverzeichnis)
<table border="1" style="width:100%;">
<tr>
<th>&nbsp;</th><th>name</th><th>index</th>
<th>crc</th><th>size</th><th>mtime</th>
<th>comp_size</th><th>comp_method</th><th>comp_s%</th>
</tr>
Der Schleifen-Zähler $i läuft von 0 bis zur Eigenschaft numFiles des ZipArchive Objekts.

Für jede Datei im Archiv werden ihre Eigenschaften an das → Array $aza zugewiesen.

Die Elemente dieses Arrays werden spaltenweise ausgegeben:
name: Pfad im Archiv, d.h. ein allfälliges Unterverzeichnis + Datei-Name
index: Fortlaufende ganze Zahl, hier identisch mit dem Schleifen-Zähler $i
crc: Kontrollsumme (Integrität der Datei, 0 für Verzeichnisse)
size: Original-Größe in Byte (0 für Verzeichnisse)
mtime: → UNIX Timestamp der letzten Änderung
comp_size: komprimierte Größe in Byte
In der Variablen $cpz wird die komprimierte Größe in % der Original-Größe berechnet.
PHP-Quelltext: Schleife über alle im Archiv enthaltenen Dateien
for ($i=0; $i<$za->numFiles;$i++) {
print "<tr>\n";
$aza = $za->statIndex($i);
print "<td>$i</td>\n";
print '<td>'.$aza['name']."</td>\n";
print '<td>'.$aza['index']."</td>\n";
print '<td>'.$aza['crc']."</td>\n";
print '<td>'.$aza['size']."</td>\n";
print '<td>'.$aza['mtime']."</td>\n";
print '<td>'.$aza['comp_size']."</td>\n";
print '<td>'.$aza['comp_method']."</td>\n";
if($aza['size']) {
$cpz=round($aza['comp_size']/$aza['size']*100,1);
}
else {$cpz='*';} print "<td>$cpz</td>\n";
print "<tr>\n";
}
Zuletzt wird das HTML-Element <table> geschlossen. HTML-Quelltext
</table>

Datenstrom

Datenstrom lesen

Wenn der Inhalt eines Archivs bekannt ist, kann man eine Datei gezielt aufsuchen. - Wesentlich schneller als das Durchlaufen aller Elemente.
Das trifft z.B. auf OpenDocument Archive zu, die nach einem fixen Schema organisiert sind.

Methode getStream liefert ein (readonly) FileHandle (hier $fp). Mit den üblichen → I/O-Methoden kann man den Inhalt lesen.
Die Verarbeitung wird hier durch die Ausgabe (print) symbolisiert.
Die Methode arbeitet auffallend rasch: Es gibt kaum Unterschiede zum Lesen der Original-Datei.
$name="sub/test.txt";
$fp=$za->getStream($name);
if($fp) {
while (!feof($fp)) {
$content = fread($fp,2);
print $content;
}
fclose($fp);
}
else {
print "Datei $name nicht gefunden.";
}

Webseiten aus einem Archiv lesen

Wenn das PHP-Programm als Server-Hilfsprogramm (CGI) arbeitet, dann wird die Ausgabe an den Webserver und weiter zum Browser geleitet:
Auf diese Weise lassen sich daher Webseiten direkt aus ZIP-Archiven lesen.
Das ist sehr effizient, wenn aus einem großen Archiv nur sporadisch einige Dateien angefordert werden (Lexika, Tutorials, ...)

Beispiel: SelfHTML benötigt als Archiv (1 Datei) ca. 8MB, ausgepackt für die >3000 Dateien 20MB + ca. 2MB für teilweise belegte Blöcke.

Das Verfahren hat in dieser einfachen Form eine gravierende Einschränkung: Es ist nur für einfache Dateien geeignet, die keine zus#tzlichern Resourcen anfordern.

Übliche Webseiten fordern weitere Dateien an (Bilder, Bibliotheken, ...) und bleiben unvollständig, wenn diese Anforderungen vom Server nicht ebenfalls an das PHP-(Unzip)-Programm geleitet werden.

Außerdem muss das Programm die → MIME-Type aller Nicht-HTML Dateien herausfinden und den passenden → HTTP-Header senden.

Verarbeitung von OpenDocument XML Dateien

Der OpenDocument Standard verwendet mehrere sehr umfangreiche 'NameSpaces', das entspricht einem großen Umfang verschiedener Befehle. Es ist eher aussichtslos, eigene Programme mit dem Anspruch zu erstellen, dass alle Befehle korrekt verarbeitet werden.

Einschränkung:

Man kann sich auf die Verarbeitung weniger wichtiger XML-Elemente (tags) beschränken, z.B. in content.xml auf die Elemente
OpenDocument XMLXHTMLBedeutung
<text:line-break/><br />Zeilen-Umbruch, Neue Zeile
<text:p></text:p><p></p>Absatz
<text:span></text:span> <span></span> einheitlich formatierter Text-Abschnitt
Eine einfache aber sehr wirksame Erweiterung ist die Berücksichtigung einfacher Formatierung:
So sieht ein formatierter Text-Abschnitt aus:
<text:span text:style-name="T1"> Das ist ein Text </text:span>

Die Definition jedes individuellen Styles finden sie in der gleichen Datei content.xml, z.B. blau und fettgedruckt
<style:style style:name="T1" style:family="text">
<style:text-properties fo:color="#0000ff" fo:font-weight="bold" style:font-name="Times New Roman"/>
</style:style>
Bei der Formatierung werden CSS (Cascading style Sheets) Regeln angewendet, genauso wie heute allgemein mit allen XML XHTML und HTML Dateien.

XML-Parser

Die Verarbeitung von XML-Text-Dateien erfordert das 'Erkennen' der tags (XML-'Befehle') und die richtige dazu passende Reaktion. Am besten dafür geeignet sind XML-Parser - Programme, die ein XML-Dokument analysieren und seine einzelnen Elemente als 'Hierarchischen Baum' an das verarbeitende Programm übergeben.
Vorteil: Fast beliebig große und komplexe Dateien werden rasch und einfach verarbeitet. Verarbeitung nach den strengen Regeln einer XML Baum-Struktur (DOM, Document Object Model).
Nachteil: Für wenig erfahrene EntwicklerInnen schwieriger zu verstehen (Einstiegs-Schwelle).

Details zum XML-Parsen mit PHP.

Reguläre Ausdrücke

sind eine standardisierte Technik zur Verarbeitung von Texten. RegExp können dazu verwendet werden, jede Text-Datei zu analysieren.
Vorteil: RegExp sind beliebig flexibel. Sie können jede Text-Datei analysieren, nicht nur XML.
Nachteil: Die Regeln der XML Baum-Struktur müssen durch das eigene Programm beigebracht werden.

Details zu Regularen Ausdrücken

Datei-Baum

Meistens wird nicht eine einzelne OpenDocument Datei verarbeitet, sondern ein ganzes Verzeichnis.
Das (interaktiv) gewählte Verzeichnis muss inklusive aller Unter-Verzeichnisse durchlaufen werden Das kann tausende von Dateien umfassen. Dazu werden 'rekursive' Unterprogramme verwendet, d.h. Programme, die 'sich selbst' aufrufen.

Details zu rekursiven Funktionen, zum Durclaufen eine kompletten Verzeichnis-Baums

PCLZIP und InfoZIP

Eine Alternative für Windows sind die Konsolen-Programme von InfoZIP. Diese Programme können ZIP-Archive ein- und auspacken und werden durch Befehle auf der Konsole ('Eingabeaufforderung') gesteuert.
Wenn die Programme ( zip, unzip ) installiert und getestet sind, dann kann man sie mit → Konsolen-Befehlen aus PHP Script-Programmen steuern.
Nachteil dieser Methode:
Spezifisch für Win-Betriebssysteme. Kann nur angewendet werden, wenn die InfoZIP Programme installiert wurden, d.h. nur für den eigenen PC oder für das eigene lokale Netzwerk (LAN).

Details zur Verwendung von PCLZIP mit PHP

Ausgewählte Links zum Thema 'ZIP'

PEAR - PHP Extension & Application Repository - zahlreiche PHP-Bibliotheken für jeden Zweck
PHPConcept - Hersteller der PclZip Bibliothek für PHP
InfoZip - Hersteller von ZIP Konsolen-Programmen für Windows-Systeme.
LibreOffice - kostenfreies Paket von Büro-Programmen für alle Sprachen und Betriebssysteme, verwendet OpenDocument-ZIP-Archive.


Fatal error: Call to undefined function write_my_modif_time() in /home/topsoft.at/www.topsoft.at/pstrainer/entwicklung/php/archive/php_zip.php on line 771