Für viele Webprojekte mit "quasistatischem" Inhalt bietet es sich an, die Ausgaben zu cachen, also zwischenzuspeichern. Die Vorteile sind:
Die hier vorgestellte Methode lässt sich auch nachträglich in Webprojekte, genauer in PHP-Skripte einbinden. Vorsicht ist jedoch geboten wenn Sie bereits Frameworks oder Template-Engines (wie zum Beispiel Smarty) benutzen, welche eigene Methoden des Cachings mitbringen, dann kann der Vorteil "dahin" sein. Meine Methode ist ideal für kleinere Projekte (wie zum Beipiel ein CMS) und ich verwende es z.B. für die fastix-Netztools und, in ähnlicher Form, für dieses CMS. (Schauen Sie mal in den Quelltext dieser Seite).
In einigen Fällen kann die Anwendung kontraproduktiv sein, dies betrifft eigentlich insbesondere die Fälle, in denen durch die theorethisch unbegrenzte Anzahl verschiedener Nutzereingaben oder durch Anfragen an unterschiedliche Dienste eine zu große Datenmenge entstehen würde. Sollten sich jedoch herausstellen, dass bestimmte Anfragen zu bestimmten Zeiten gehäuft auftreten, dann kann sich das temporäre Caching, so wie ich es hier vorstelle, dennoch lohnen. Testen Sie verschienden Einstellungen der Gütigkeitsdauer des Caches. Fallm es immer noch zu viel ist: Eine Methode, wie man Daten zwischenspeichert, die sonst erst auf aufwendige Weise, z.B. von anderen Servern geholt oder berechnet werden, habe ich im Artikel "PHP: Speichern und Lesen von Daten: Arrays in und aus Dateien" bereits beschrieben.
Zunächst sollte für die Speicherung ein Verzeichnis bereit stehen. Dieses Verzeichnis muss der Webserver, genauer der "Benutzer" den der Webserver benutzt, schreiben und natürlich lesen sowie "betreten" dürfen, das lässt sich an einer (ssh-Shell) oder mit FTP einrichten.
~> mkdir cache; ~> echo 'deny from all' > cache/.htaccess ~> chmod 777 cache; (oder ~> chown wwwrun cache) (Natürlich kann auch das PHP-Skript prüfen, ob es das Verzeichnis gibt und es anlegen. Das müsste nur programmiert werden.) Zum PHP-Skript: <?php /* Festlegen der Konfiguration */ define('FTX_CACHE_DIR', './cache/'); # Das Cache-Verzeichnis als absoluter oder relativer Pfad auf dem Dateisystem define('FTX_CACHE_TIME',3600); # Wie viele Sekunden soll der Cache gültig sein? # 0 oder FALSE - Caching ist aus # '~' - unbegrenzt (Vorsicht! Sie müssen den Cache "manuell" löschen) define('FTX_CACHE_USE_POST',TRUE); # Sollen mit POST gesendete Daten beachtet werden? define('FTX_CACHE_USE_COOKIE',TRUE); # Sollen Cookies beachtet werden? define('FTX_CACHE_USE_SESSION',TRUE);# Sollen SESSIONS beachtet werden? /* Wichtig! Eventuell muss session_start() aus dem originalen Skript hier her vorgezogen werden. */ /* Das Ermitteln des Namens für das Cachefile */ if (FTX_CACHE_TIME) { $s=$_SERVER['REQUEST_URI']; /* Falls POST-Daten gesendet wurden: */ if ( FTX_CACHE_USE_POST && isset($_POST) && count($_POST) ) { $s.=serialize($_POST); } /* Falls Cookies gesendet wurden: */ if ( CACHE_USE_COOKIE && isset($_COOKIE) && count($_COOKIE) ) { $s.=serialize($_COOKIE); } /* Falls eine Session besteht: */ if ( FTX_CACHE_USE_SESSION && isset($_SESSION) && count($_SESSION) ) { $s.=serialize($_SESSION); } /* Der Name muss sicher sein, denn er wird in das Dateisystem geschrieben - md5() liefert was wir brauchen */ define ('FTX_CACHE_FILE', FTX_CACHE_DIR . md5($s) . '.gz'); /* Falls die Frage, ob $s existiert und einen Wert in Ihrem bisherigen Skript noch eine Bedeutung hat */ unset($s); /* Soll die Lebensdauer des Caches begrenzt sein? */ if ( '~' != FTX_CACHE_TIME ) { /* Jetzt müssen wir nachsehen, ob ein Cachefile existiert, welches eventuell veraltet ist: */ if ( filemtime(FTX_CACHE_FILE) < (time()-FTX_CACHE_TIME) ) { /* und das veraltete Cachefile löschen: */ unlink(FTX_CACHE_FILE); } } /* Prüfen, ob Cachefile (jetzt noch) vorhanden und lesbar ist: */ if ( file_exists(FTX_CACHE_FILE) && is_readable(FTX_CACHE_FILE) ) { /* Die Webseiten können natürlich auch lokal (im Browsercache oder auf einem Proxyserver) gecached werden: */ if ( '~' == FTX_CACHE_TIME ) { /* 24 Stunden statt unendlich */ $extCacheTime = 84600; } else { $extCacheTime = FTX_CACHE_TIME; } if ( $extCacheTime ) { header("Expires: " . gmdate("D, d M Y H:i:s", time() + $extCacheTime) ." GMT"); header("Cache-Control: public, max-age=" . $extCacheTime); } /* Mag der User-Agent gezippte Daten? */ if ( false===strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') ) { /* Falls nicht packen wir nämlich für Ihn aus: */ exec('cat '.FTX_CACHE_FILE.'|gunzip'); exit; } else { /* Falls ja, und das ist meistens der Fall, senden wir den Header und die gepackten Daten */ header('Vary: Accept-Encoding'); header('Content-Encoding: gzip'); readfile(FTX_CACHE_FILE); exit; } } } /* Wenn das Skript hier noch nicht über ein exit gestolpert ist, dann muss eben alles neu errechnet werden. Um die Ausgaben in einem Puffer einzufangen bemühen wir 'ob_start()'; */ ob_start(); /* ######################################################################################## # # # Ihr bisheriges PHP-Skript bleibt (bis auf das eventuelle Vorziehen des # # Startes der Session unangetastet! # # Es sollte an dieser Stelle stehen und diesen Kommentar ersetzen. # # # */ ######################################################################################## /* Wir prüfen, ob überhaupt gecacht wird: */ if ( FTX_CACHE_TIME && defined(FTX_CACHE_FILE) ) { /* Schreiben des gezippten Cache-Files: */ file_put_contents(FTX_CACHE_FILE, gzencode(ob_get_contents())); /* Suchen und Löschen veralteter Cache-Daten: */ if ( '~' != FTX_CACHE_TIME ) { $d = dir(FTX_CACHE_DIR); while ( FALSE !== ($f = $d->read()) ) { if ( strpos($f,'.gz') ) { $file=FTX_CACHE_DIR.$f; if ( filemtime($file) < (time()-FTX_CACHE_TIME) ) { unlink ($file); } } } } } /* In jedem Fall geben wir die Daten aus dem Puffer aus: */ ob_end_flush(); /* Nur um zu zeigen, dass wir fertig sind */ ?>
Die Benutzung ist frei. Höfliche Mitmenschen notieren im Quellcode als Kommentar die Herkunft.
Fehlermeldungen oder Anfragen hinterlassen Sie bitte als Kommentar oder Sie senden mir diese als Email.