Start · Sprachen · PHP · Referenz · ZipArchive

ZipArchive

Klasse

Ermöglicht das Erstellen, Lesen, Ändern und Entpacken von ZIP-Archiven direkt in PHP.

seit PHP 5.2.0 Kategorie: io

Signatur

class ZipArchive implements Countable

Beschreibung

ZipArchive ist eine objektorientierte Klasse zur Arbeit mit ZIP-Dateien. Sie erlaubt es, Archive zu öffnen oder neu anzulegen, Dateien und Verzeichnisse hinzuzufügen, umzubenennen, zu löschen sowie Inhalte direkt aus Strings einzufügen – ohne temporäre Dateien auf dem Dateisystem.

Typische Einsatzgebiete sind das Erstellen von Download-Archiven (z. B. mehrere Dateien als ZIP ausliefern), das automatisierte Entpacken hochgeladener Archive sowie das Durchsuchen und Modifizieren bestehender ZIP-Pakete in Deployment-Skripten oder Build-Prozessen.

Die Klasse setzt die libzip-Bibliothek voraus, die ab PHP 7.4 fest eingebunden ist. Für ältere Versionen muss die zip-Extension explizit aktiviert sein. Mit ZipArchive::open() wird ein Archiv geöffnet; alle Änderungen werden erst beim Aufruf von ZipArchive::close() oder beim Zerstören des Objekts physisch geschrieben.

Über die Konstanten der Klasse (z. B. ZipArchive::CREATE, ZipArchive::OVERWRITE) lässt sich das Verhalten beim Öffnen präzise steuern. Seit PHP 8.0 gibt open() bei Fehlern true oder einen Integer-Fehlercode zurück, der mit den ZipArchive::ER_*-Konstanten verglichen werden kann.

Parameter

Name Typ Default Beschreibung
$filename Pflicht string Pfad zur ZIP-Datei, die geöffnet oder erstellt werden soll. Wird an ZipArchive::open() übergeben.
$flags int 0 Kombination aus Öffnungs-Flags: ZipArchive::CREATE (anlegen wenn nicht vorhanden), ZipArchive::OVERWRITE (überschreiben), ZipArchive::EXCL (Fehler wenn bereits vorhanden), ZipArchive::RDONLY (nur lesen).

Rückgabewert

Typ

Beispiele

ZIP-Archiv erstellen und Dateien hinzufügen

<?php
$zip = new ZipArchive();
$result = $zip->open('/tmp/meinarchiv.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);

if ($result !== true) {
    throw new RuntimeException('ZIP konnte nicht geöffnet werden. Fehlercode: ' . $result);
}

// Lokale Datei unter neuem Namen im Archiv ablegen
$zip->addFile('/var/www/html/bericht.pdf', 'dokumente/bericht.pdf');

// Inhalt aus einem String direkt als Datei ins Archiv schreiben
$zip->addFromString('info.txt', "Erstellt am: " . date('d.m.Y') . "\n");

// Leeres Verzeichnis anlegen
$zip->addEmptyDir('bilder');

$zip->close();
echo "Archiv erfolgreich erstellt.\n";
Archiv erfolgreich erstellt.

ZIP-Archiv entpacken

<?php
$zip = new ZipArchive();

if ($zip->open('/tmp/meinarchiv.zip') !== true) {
    throw new RuntimeException('Archiv konnte nicht geöffnet werden.');
}

$zielVerzeichnis = '/tmp/entpackt/';
if (!is_dir($zielVerzeichnis)) {
    mkdir($zielVerzeichnis, 0755, true);
}

// Alle Dateien ins Zielverzeichnis entpacken
$zip->extractTo($zielVerzeichnis);

echo 'Enthaltene Dateien: ' . $zip->numFiles . "\n";

// Einzelne Datei per Index auslesen
for ($i = 0; $i < $zip->numFiles; $i++) {
    $info = $zip->statIndex($i);
    echo $info['name'] . ' (' . $info['size'] . ' Bytes)' . "\n";
}

$zip->close();
Enthaltene Dateien: 3 dokumente/bericht.pdf (204800 Bytes) info.txt (23 Bytes) bilder/ (0 Bytes)

Hochgeladenes ZIP-Archiv sicher verarbeiten

<?php
// Sicherheits-Check: Nur ZIP-Dateien akzeptieren, Pfad-Traversal verhindern
$uploadedFile = $_FILES['archiv']['tmp_name'] ?? '';
$zielBasis = realpath('/var/www/uploads/') . '/';

$zip = new ZipArchive();
if ($zip->open($uploadedFile) !== true) {
    die('Ungültiges Archiv.');
}

for ($i = 0; $i < $zip->numFiles; $i++) {
    $entry = $zip->getNameIndex($i);
    // Pfad-Traversal-Angriffe abwehren
    $realEntry = realpath($zielBasis . $entry);
    if ($realEntry === false || strpos($realEntry, $zielBasis) !== 0) {
        $zip->close();
        die('Sicherheitsproblem: Pfad außerhalb des Zielverzeichnisses.');
    }
}

$zip->extractTo($zielBasis);
$zip->close();
echo 'Archiv sicher entpackt.';
Archiv sicher entpackt.

// Wichtig · Fallstricke

Sicherheit – Zip Slip: Beim Entpacken von nicht vertrauenswürdigen Archiven (z. B. Nutzer-Uploads) müssen alle Eintrags-Pfade auf Pfad-Traversal (../) geprüft werden, bevor extractTo() aufgerufen wird. Ein bösartiges Archiv könnte sonst Dateien außerhalb des Zielverzeichnisses anlegen. Das dritte Beispiel demonstriert diese Prüfung.

Ressourcen: Nicht gespeicherte Änderungen gehen verloren, wenn close() nicht aufgerufen wird. Seit PHP 8.0 implementiert ZipArchive Countable; count($zip) liefert die Anzahl der Einträge.

Passwortschutz: Mit ZipArchive::setPassword() kann ein Passwort für verschlüsselte Archive gesetzt werden. Die Verschlüsselungsstärke hängt von der libzip-Version ab; für sensible Daten sollte ein dediziertes Verschlüsselungswerkzeug bevorzugt werden.

Große Archive: Bei sehr großen Archiven empfiehlt sich die Beachtung des PHP-Speicherlimits. addFromString() hält den gesamten Inhalt im Speicher; für große Dateien ist addFile() vorzuziehen.