Per gzip komprimierte Daten senden

Wie Daten per gzip komprimiert und anschließend an den Besucher gesendet werden können

Die Daten einer Webseite werden gewöhnlich ohne Komprimierung an den Besucher gesendet.
Möglich ist es aber auch, diese Daten zuvor per gzip zu komprimieren.
Dadurch wird die Menge der gesendeten Daten häufig erheblich reduziert.
Dies verringert nicht nur den Traffic auf der Seite, sondern beschleunigt auch den Ladevorgang bei langsamen Verbindungen.

Am einfachsten ist die Verwendung von gzip indem die Funktionen ob_start() und ob_end() verwendet werden.
ob_start() muss vor der ersten Ausgabe stehen, ob_end() nach der letzten.
Zusätzlich muss an ob_start() noch "ob_gzhandler" übergeben werden.
Diese Callback-Funktion sorgt für die eigentliche Komprimierung.
Wird sie nicht übergeben, dann werden die Daten unkomprimiert gesendet.

PHP-Code
<?php
    ob_start('ob_gzhandler'); // gzip und Ausgabepufferung aktivieren
	echo("Diese Ausgabe wird automatisch per gzip komprimiert\n");
	echo("Diese ebenfalls.");
	ob_end_flush(); // Ausgabepufferung beenden und Daten senden
?>
Ausgabe
Diese Ausgabe wird automatisch per gzip komprimiert
Diese ebenfalls.

Die zweite Variante ist es, die Daten selbst zu komprimieren und auch das Senden eigenhändig durchzuführen.
Einfach per gzcompress() komprimierten Content zu senden reicht allerdings nicht.
Es muss dem Browser auch mitgeteilt werden, dass es sich um komprimierte Inhalte handelt.
PHP-Code
<?php
	$str = 'Das ist ein Beispielstring.';
	$compressed = gzcompress($str, 9);
	$data = array(
			'str'=>$compressed,	// Die komprimierten Daten
			'crc32'=>crc32($str),	// Eine CRC32-Checksum der unkomprimierten Daten
			'length'=>strlen($str)	// Die Zeichenlänge der unkomprimierten Daten
		);

	// ... hier könnten die Daten z.B. per Datei, DB oder Memcache zwischengespeichert und wieder eingeladen werden ...

	// Prüfen, ob der Besucher per gzip komprimierte Daten interpretieren kann
	if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) {
		// Signalisieren, dass gzip-Daten gesendet werden
    		header('Content-Encoding: gzip');
		// gzip-Daten senden, inklusive Checksum und Zeichenlänge
    		echo("\x1f\x8b\x08\x00\x00\x00\x00\x00"
    			.substr($data['str'], 0, -4)
    			.pack('V', $data['crc32'])
    			.pack('V', $data['length'])
		);
	} else {
		// Falls der Besucher kein gzip interpretieren kann werden
		// die Daten unkomprimiert gesendet
		echo(gzuncompress($data['str']));
	}
?>
Ausgabe
Das ist ein Beispielstring.

Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0