Start · Sprachen · PHP · Referenz · deflate_add

deflate_add

Funktion

Komprimiert einen Datenblock inkrementell mit dem Deflate-Algorithmus unter Verwendung eines zuvor erstellten <code>DeflateContext</code>.

seit PHP 7.0.0 Kategorie: io

Signatur

deflate_add(DeflateContext $context, string $data, int $flush_mode = ZLIB_SYNC_FLUSH): string|false

Beschreibung

deflate_add ermöglicht die schrittweise (inkrementelle) Komprimierung von Daten mit dem Deflate-Algorithmus. Im Gegensatz zu gzdeflate oder gzcompress, die den gesamten Input auf einmal verarbeiten, kann deflate_add in einer Schleife mit beliebig vielen Datenblöcken aufgerufen werden. Dies ist besonders nützlich beim Verarbeiten von großen Datenströmen, bei denen der gesamte Inhalt nicht gleichzeitig im Speicher gehalten werden soll.

Die Funktion benötigt einen DeflateContext, der zuvor mit deflate_init erstellt wurde. Der Kontext speichert den internen Kompressionszustand zwischen den Aufrufen. Über den Parameter $flush_mode wird gesteuert, wie die komprimierten Daten aus dem internen Puffer ausgegeben werden: ZLIB_NO_FLUSH puffert aggressiv, ZLIB_SYNC_FLUSH gibt alle ausstehenden Daten aus, und ZLIB_FINISH schließt den Datenstrom ab und gibt alle verbleibenden Daten inklusive Abschluss-Header aus.

Beim letzten Aufruf in einer Sequenz sollte stets ZLIB_FINISH als Flush-Modus verwendet werden, damit der erzeugte Ausgabestrom korrekt abgeschlossen wird und von Dekomprimierern vollständig gelesen werden kann.

Die Funktion ist Teil der Zlib-Extension und steht nur dann zur Verfügung, wenn PHP mit Zlib-Unterstützung kompiliert wurde.

Parameter

Name Typ Default Beschreibung
$context Pflicht DeflateContext Ein mit deflate_init erstellter Deflate-Kontext, der den internen Kompressionszustand enthält.
$data Pflicht string Der Datenblock, der komprimiert werden soll. Kann ein beliebiger binärer String sein.
$flush_mode int ZLIB_SYNC_FLUSH Steuert das Flush-Verhalten des Kompressionspuffers. Mögliche Werte: ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK oder ZLIB_FINISH. Beim letzten Block immer ZLIB_FINISH verwenden.

Rückgabewert

Typ
string|false
Beschreibung
Gibt den komprimierten Datenstrom als String zurück, oder false bei einem Fehler (z. B. ungültiger Kontext oder fehlerhafter Flush-Modus).

Beispiele

Einfache inkrementelle Komprimierung eines Strings

<?php
// Deflate-Kontext mit Standard-Komprimierungslevel erstellen
$context = deflate_init(ZLIB_ENCODING_DEFLATE, ['level' => 6]);

$compressed  = deflate_add($context, 'Hallo, ', ZLIB_NO_FLUSH);
$compressed .= deflate_add($context, 'Welt! ', ZLIB_NO_FLUSH);
$compressed .= deflate_add($context, 'Das ist inkrementelle Komprimierung.', ZLIB_FINISH);

echo 'Komprimierte Größe: ' . strlen($compressed) . ' Bytes' . PHP_EOL;

// Zur Überprüfung dekomprimieren
$decompressed = gzinflate($compressed);
echo 'Dekomprimiert: ' . $decompressed . PHP_EOL;
Komprimierte Größe: 33 Bytes Dekomprimiert: Hallo, Welt! Das ist inkrementelle Komprimierung.

Große Datei blockweise komprimieren und in eine .gz-Datei schreiben

<?php
$inputFile  = '/pfad/zur/grossen-datei.txt';
$outputFile = '/pfad/zur/ausgabe.gz';

$context = deflate_init(ZLIB_ENCODING_GZIP, ['level' => 9]);

$in  = fopen($inputFile, 'rb');
$out = fopen($outputFile, 'wb');

if ($in === false || $out === false) {
    die('Datei konnte nicht geöffnet werden.');
}

while (!feof($in)) {
    $chunk      = fread($in, 8192); // 8 KB-Blöcke
    $flushMode  = feof($in) ? ZLIB_FINISH : ZLIB_NO_FLUSH;
    $compressed = deflate_add($context, $chunk, $flushMode);

    if ($compressed === false) {
        die('Fehler bei der Komprimierung.');
    }

    fwrite($out, $compressed);
}

fclose($in);
fclose($out);

echo 'Datei erfolgreich komprimiert.' . PHP_EOL;
Datei erfolgreich komprimiert.

// Wichtig · Fallstricke

Wichtig: Wird der letzte Datenblock nicht mit ZLIB_FINISH abgeschlossen, ist der erzeugte komprimierte Strom unvollständig und kann von Dekomprimierern möglicherweise nicht korrekt gelesen werden.

Der DeflateContext ist nach einem Aufruf mit ZLIB_FINISH verbraucht und sollte nicht mehr verwendet werden. Für eine neue Komprimierung muss ein neuer Kontext mit deflate_init erstellt werden.

ZLIB_NO_FLUSH bietet die beste Komprimierungseffizienz, da der Encoder mehr Daten puffern kann, bevor er ausgibt. ZLIB_SYNC_FLUSH und ZLIB_FULL_FLUSH eignen sich für Streaming-Szenarien, bei denen der Empfänger Zwischendaten sofort verarbeiten soll.