|
Software- und Webentwicklung Planung, Programmierung und Administration
UML, JavaScript/DOM, ASP, JSP, PHP, Apache, MySQL, Python, Perl (...) |
|
Themen-Optionen | Ansicht |
21.11.2004, 00:21 | #1 (permalink) |
Registriert seit: 20.11.2004
Beiträge: 59
|
[Tutorial] g(e)zip(pt) surft sichs besser
So, dann mach ich noch einen zum Einstand
Ihr kennt das bestimmt. Die Anbindung Eures Servers ist eh schon nicht die Beste. Die Besuchzahlen sind ganz gut und laufend beschweren sich irgendwelche Modemnoobs, dass der Seitenaufbau zu lange dauert. Dann habt Ihr optimiert und gemacht und trotzdem hängen diese nicht DSLler noch 5 Sekunden vor Eurer Seite und warten sich nen Wolf. Das muss nicht so sein. Seit einige Jahren verwenden moderne Browser ein Verfahren, indem Webseiten on the fly mit gzip gepackt werden und beim User wieder entpackt werden. Da es sich um Textdateien handelt ist diese Methode besonders effektiv. Die Frage ist nur, wie setzt man das am besten um. Seit PHP 4 gibt es die Möglichkeit die Daten per ob_gzhandler sofort in der Pufferung zu packen. Sie auch da :hier: http://de.php.net/manual/de/function.ob-start.php. Dies ist an sich eine feine Sache, aber nicht immer sinnvoll. Die größten Nachteile des ob_gzhandlers: - Man kann den Kompressionsgrad nicht einstellen und ist von den PHP Einstellungen abhängig - Man kann die Kompression nicht für einzelne Dateitypen ausschalten - Es gibt in PHP immer wieder Probleme, wenn man den Puffer leeren muss Also brauchen wir eine extra Klasse/Funktion mit der wir das machen. Das Folgende Script ist nur ein Vorschlag. Es ist in Teilen an dieses da :hier: angelehnt http://leknor.com/code/php/class.gzi...de.0.6.php.txt - nur etwas moderner und mit mehr Einstellungsmöglichkeiten. Ausserdem sollte es auch etwas schneller sein, das hab ich aber nicht getestet. Bugs dürfte es keine mehr geben. Features: - minimaler/maximaler Kompressionsgrad einstellbar - bestimmte Dateitypen werden von der Komprimierung ausgeschlossen - Die Kompression passt sich an die Serverload an, d. h. ist der Server sehr ausgelastet wird die Kompression runtergesetzt - die maximale Serverauslastung ist einstellbar - Auch eine feste Komprimierung ist einstellbar - Sehr einfache Einbindung - Bei einem Fehler gibt es keine Einschränkung. Es wird einfach nur der Content ausgegeben - kompatibel mit allen PHP Versionen ab Version 4 mit zlib Bibliothek - Ihr könnt zusätzliche Informationen über die Bearbeitung anzeigen (Serverload, CPU Time, Kompression, Ersparnis) Die Einbindung Ganz unten seht Ihr einen Beispielcode, wie Ihr das einbinden könnt. Code:
<?php /** * This class checks the output buffer * zips the input if you want to * @param: int $MaxServerload the maximum serverload * @param: int $MinCompression the minimum compression level * @param: int $MaxCompression the maximum compression level * @input: mixed $level the compression level * @input: bool $debug use debug mode (no compression) * @input: bool $showSize show the compression in html * @return: string the output */ class Output { /** * Public vars */ var $MaxServerload = '2'; var $MinCompression = '2'; var $MaxCompression = '8'; /** * Private vars */ var $contents; var $gzdata; var $encoding; var $crc; var $size; var $gzsize; var $serverload; var $level; var $debug; var $showSize; /** * Constructor */ function Output($level='3', $debug=false, $showSize=true) { $this->level = $level; $this->debug = $debug; $this->showSize = $showSize; } /** * Let's work a bit with the buffer * @input string $buffer the output buffer * @return string $buffer the new output buffer */ function gz($buffer) { $this->contents = $buffer; /* Find out which encoding to use */ $this->encoding = false; /** * Check the best compress version for the browser * Use the @ to prevent bots from saving an error */ if (isset($_SERVER['HTTP_ACCEPT_ENCODING'])) { if(@strpos(' ' . $_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip') !== false) { $this->encoding = 'x-gzip'; } if(@strpos(' ' . $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) { $this->encoding = 'gzip'; } } /* Find out more about the file which should be compressed */ $filetype = substr($this->contents, 0, 4); if(substr($filetype, 0, 2) === '^_') { /* gzip data */ $this->encoding = false; } elseif(substr($filetype, 0, 3) === 'GIF') { /* gif images */ $this->encoding = false; } elseif(substr($filetype, 0, 2) === "\xFF\xD8") { /* jpeg images */ $this->encoding = false; } elseif(substr($filetype, 0, 4) === "\x89PNG") { /* png images */ $this->encoding = false; } elseif(substr($filetype, 0, 3) === 'FWS') { /* Shockwave Flash */ $this->encoding = false; } elseif(substr($filetype, 0, 2) === 'PK') { /* pk zip file */ $this->encoding = false; } elseif($filetype == '%PDF') { /* PDF File */ $this->encoding = false; } /* There might be some Problems */ if(headers_sent() || connection_status() != 0 || !$this->encoding || $this->contents === false || !extension_loaded('zlib') || @ini_get('output_handler') == 'ob_gzhandler') return $this->contents; /* We need a level to compress the output */ if($this->level == 'auto') { /* Let's find out, which compression level is ok for the system */ if(@file_exists('/proc/loadavg')) { $fh = @fopen('/proc/loadavg', 'r'); $load_averages = @fread($fh, 64); @fclose($fh); $load_averages = @explode(' ', $load_averages); $this->serverload = ((float)$load_averages[0]+(float)$load_averages[1]+(float)$load_averages[2])/3; } elseif(preg_match('/averages?: ([0-9\.]+),[\s]+([0-9\.]+),[\s]+([0-9\.]+)/i', @exec('uptime'), $load_averages)) { $this->serverload = ((float)$load_averages[1]+(float)$load_averages[2]+(float)$load_averages[3])/3; } else { $this->serverload = '1'; } $this->level = (1-($this->serverload/$this->MaxServerload))*10; /* Ok, that looks terrible, but its faster than a min/max construction */ $this->level = ($this->level > $this->MinCompression) ? (($this->level < $this->MaxCompression) ? intval($this->level) : $this->MaxCompression) : $this->MinCompression; } /* The introduction for the compressed data */ $this->gzdata = "\x1f\x8b\x08\x00\x00\x00\x00\x00"; /** * Maybe you want some extra information * This is not the ideal because you need to * compress the output twice */ if($this->showSize) { /* We need some vars for the information */ $uncompressed = round(strlen($this->contents)/1024, 2); $start = get_microtime(); $compressed = round(strlen(gzcompress($this->contents, $this->level))/1024, 2); $time = round((get_microtime()-$start)*1000, 2); $savingkb = $uncompressed-$compressed; $saving = @round($savingkb/$uncompressed*100, 0); $showlevel = ($this->level == 'auto') ? ' (auto)' : ''; /* Shows some informations */ $this->contents .= "\n".'<!--'."\n\t".'Compression level: '.$this->level.$showlevel."\n\t".'Original size: '.$uncompressed.' kb'."\n\t".'New size: '.$compressed.' kb'."\n\t".'Saving: '.$savingkb.' kb ('.$saving.' %)'."\n\t".'Time: '.$time.' ms'."\n\t".'Serverload: '.round($this->serverload, 2)."\n".'-->'; } /* Compress the output */ $this->size = strlen($this->contents); $this->gzdata .= substr(gzcompress($this->contents, $this->level), 0, - 4); $this->gzdata .= pack('V', crc32($this->contents)); $this->gzdata .= pack('V', $this->size); $this->gzsize = strlen($this->gzdata); /* Maybe you just want to see the result of all this */ if($this->debug) { $this->contents = $this->contents."\n".'<!--'."\n\t".'gzip is in debug mode. The shown output is uncompressed'."\n".'-->'; return $this->contents; } /* Send the special header */ header('Content-Encoding: '.$this->encoding); header('Content-Length: '.$this->gzsize); /* Exit the class and send all data to the browser */ return $this->gzdata; } } /** * construct the object */ $output = new Output('auto', false, true); /** * Start the output buffering */ ob_start(array(&$output, 'gz')); ?> Geändert von Dr. Doom (21.11.2004 um 00:24 Uhr). |
21.11.2004, 10:50 | #2 (permalink) |
|
AW: [Tutorial] g(e)zip(pt) surft sichs besser
Erwähnen sollte man vielleicht noch das die Klasse ebenfalls wie ob_gzhandlers nachcheckt ob der Client (Browser) überhaupt in der Lage ist komprimierte Inhalte zu lesen.
Du verwendest für meinen Geschmack ein paar "@" zuviel. Du könntest auch wenn du die Fehlerausgabe verhindern willst die komplette Fehlerausgabe deaktivieren: PHP-Code:
Da hättest du jetzt bei PHP 5 leichtes Spiel (=> Exception Handling). Ansonsten #1 Schön zu sehen das hier Jemand mal etwas postet. *rolleyes*
__________________
https://savetheinternet.info/ |
21.11.2004, 14:46 | #4 (permalink) |
Registriert seit: 20.11.2004
Beiträge: 59
|
AW: [Tutorial] g(e)zip(pt) surft sichs besser
Fürs Error Reporting hab ich eine eigene Klasse, die mir die Fehler loggt und wenn ich das will auch direkt den fehlerhaften Quelltext anzeigt. 2 @s könnten weg - das stimmt schon.
|
30.05.2009, 23:15 | #5 (permalink) |
Registriert seit: 30.05.2009
Beiträge: 4
|
Hallo Dr. Doom, ist zwar lange her, dass du diesen Tutorial hier gepostet hast womit ich dir auch sehr Dankbar bin. Habe so was ähnliches eigentlich gesucht und ist dir echt sehr gut gelungen. Doch wäre ich ebenfalls sehr an deinem Error Reporting Klasse auch interessiert. Da es zu deinem Output Klasse passt. Wäre dir sehr Dankbar, wenn du dieses ebenfalls veröffentlichen würdest oder eventuell vielleicht auch mir per Email schicken würdest. Gruß Daniel |
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1) | |
Themen-Optionen | |
Ansicht | |
|
|