PHP-Klasse cache
EinleitungVoraussetzung
Versionsgeschichte
Installation
Einbindung in deine Webseite
Dokumentation
Einleitung
Manche Aufgaben beim verarbeiten eines Webserver-Requests brauchen Zeit. Sei es ein rekursiver Verzeichnisscan, ein aufwändiges Query oder Requests auf andere Server.Solche zeitaufwändigen Aufgaben möchte man nicht bei jedem Seitenaufruf ausführen, weil es den Seitenaufbau immer arg verlangsamt, sondern nur "gelegentlich". Dazu speichert man einmalig das Ergebnis in einem Cache und verwendet den Cache solange man es für sinnvoll erachtet.
Diese Klasse verwende ich auf dieser Webseite zum Cachen von HTML-Code, RSS-Daten und Grafiken.
Weiterhin ist diese Klasse in Version 1 auch seit einigen Jahren auf der Webseite vom Schweizer Radio DRS (SRF Radio; www.drs.ch) im Einsatz.
Seitenanfang
Voraussetzung
- PHP 5
Seitenanfang
Versionsgeschichte
- 2012-05-17 - Version 2.1
- geänderte Methode: isExpired() liefert Wert als bool (vorher Wert in Sekunden);
- neue Methode: iExpired() liefert Wert in Sekunden
- 2012-01-31 - Version 2.0
- neu: es können alle serialisierbaren Variablen gecacht werden - also auch Arrays und Objekte - nicht nur Strings, wie in Version 1
- Methode write() erweitert: als 2. Parameter kann eine Verfallszeit mitgegeben werden, die mit in der Cachedatei gespeichert wird
- neue Methode: isExpired() zum einfacheren Feststellen, ob Cache veraltet ist (bedingt Verwendung des neuen 2. Parameters für write())
- neue Methode: isNewerThanFile([Referenzdatei]) - zum einfacheren Feststellen, ob Cache veraltet ist
- neue Methode: cleanup() - Löschen alter Cachedateien
- 2011-08-27 - Version 1.1 - mehr Kommentare im PHP Code; sCacheFile is private
- 2009-07-20 - Version 1.0 - erste öffentliche Version
Seitenanfang
Installation
Download
Download:
cache_class_php.zip (13 kB)
Auspacken
Kopieren Sie die Datei cache.class.php in ihr PHP-Verzeichnis. Sie kann auch in einem beliebigen Unterordner abgelegt werden.
Seitenanfang
Einbindung in deine Webseite
Basics: Füllen und Lesen des Caches
(1)
Mit einer include_once/ require_once ist die Klasse zu laden.
(2)
Mit der Initialisierung sind 2 Parameter anzugeben:- der Name deiner Applikation / deines Moduls
Im Hintergrund wird für die Applikation ein Unterverzeichnis angelegt. Dann können verschiedene Module dieselbe ID verwenden. Und man kann einfacher das Cacheverzeichnis eines Moduls leeren. - eine ID für die Daten
Die ID kann ein beliebiger Text oder auch eine Zahl sein. Bei RSS Feeds kann man so direkt die URL des Feeds mitgeben; bei Datenbank-Queries kann es eine Basis ID sein, für die die Daten ermittelt wurden.
(3)
Die Funktionen read() und write([Daten , [Expire]]) lesen bzw. schreiben den Cache-Inhalt.
(4)
Mit am wichtigsten ist die Frage: wie lange man ich den Cache verwenden und wann muss ich diesen erneuern?
Es gibt mehrere Varianten:
-
Zunächst werden die Daten mit write([Daten]) geschrieben.
Mit der Funktion getAge() kann man das Alter des Caches in Sekunden ermitteln. Ist es false, so gibt es noch keinen Cache.
Man kann den Cache anlegen/ erneuern lassen, wenn noch kein Cache existiert oder das Alter des Cache eine Toleranzschwelle übersteigt.
Das ist eine Methode von Version 1; es sollte bevorzugt eine der nachfolgend erwähnten Varianten gewählt werden. - mit der Methode write() gibt man als 2. Paramter eine Verfallszeit (Expire)
in Sekunden mit. Diese Verfallszeit wird mit in der Cachedatei abgelegt.
Dann kann man mit isExpired() feststellen, ob der Cache veraltet ist (negative Werte = Zeit in Sekunden bis Verfall; positive Werte = wie lange der Cache verfallen ist) - Wenn man den Cache basierend auf
einer anderen Datei aufbaut, kann man die Zeitstempel von Quelldatei und Cachedatei
zum Vergleich heranziehen.
Die Funktion isNewerThanFile([Dateiname-der-Referenzdatei]) gibt die Differenz der letzten Änderung in Sekunden zurück (negative Werte = Cachdatei ist älter als Referenzdatei).
Die Referenzdatei ist der komplette Dateiname, den der Webserver finden können muss (lokal oder NFS Share etc.).
Beispiele wären: ein verkleinertes Vorschaubild wird erst dann erneuert, wenn sich die Quelldatei geändert hat; oder: meine Tabelle mit Batch-Kommandos und Beispielen basieren auf einer CSV Datei - der Cache wird erst neu geschrieben, wenn ich die CSV Datei aktualisiere.
$sContent=''; $iTtl=60*5; // 5 min als max. zulaessiges Alter require_once("/php/cache.class.php"); $myCache=new Cache("mein-modul","Aufgaben-ID"); if($myCache->isExpired()) { // Cache existiert nicht oder ist veraltet // hier folgt Code, der $sContent neu auffuellt ... $sContent=... // ... und im Cache ablegen $myCache->write($sContent, $iTtl); } else { // Cache-Daten lesen $sContent=$myCache->read(); } // Ausgabe echo $sContent;PHP: cache - einfacher Code-Rumpf
... und ein Beispiel zu 3) zum Vergleich des Zeitstempels. $sCsvFile enthält nachfolgend den Dateinamen des Quellfiles:
require_once("/php/cache.class.php"); $sCsvFile="Name_der_Quelldatei.csv" $myCache=new Cache("mein-modul","Aufgaben-ID"); $sContent=$myCache->read(); // einmal den Inhalt lesen // Vergleich des Alters des Cache mit dem einer Referenzdatei if (!$sContent || !$myCache->isNewerThanFile($sCsvFile)) { // hier folgt Code, der $sContent neu auffuellt ... $sContent=... // ... und im Cache ablegen $myCache->write($sContent); }; // Ausgabe echo $sContent;PHP: cache - Beispiel mit Vergleich des Zeitstempels einer Referenzdatei
Löschen von Cachefiles
Man kann von einem zu cachenden Inhalt einen einzelnen Cache gezielt löschen. Dazu muss das entsprechende Objekt initialisiert und die die Methode delete() aufgerufen werden.
require_once("/php/cache.class.php"); $myCache=new Cache("mein-modul","Aufgaben-ID"); $myCache->delete(); // einzelnen Cache loeschenPHP: cache - Beispiel mit Vergleich des Zeitstempels einer Referenzdatei
Um im Cacheverzeichnis alle Cache-Dateien löschen, die älter als n Sekunden sind, gibt es die cleanup-Methode. Das Cache-Objekt ist mit einer beliebigen Modul-ID zu initialisieren.
require_once("/php/cache.class.php"); $o=new Cache("mein-modul"); $o->cleanup(60*60*24*1); // alle Cachefiles des Moduls "mein-modul" älter 1 Tag löschenPHP: Löschen des Caches eines Moduls
Initialisiert man die Klasse ganz ohne Modul und ruft die cleanup Methode auf, so werden alle cachefiles aller Module aufgeräumt.
require_once("/php/cache.class.php"); $o=new Cache(); $o->cleanup(0); // alle Cachefiles aller Module löschenPHP: Löschen des Caches aller Module
Anm.:
- Der Parameter von cleanup() ist das max. erlaubte Alter der Cachedateien in Sekunden. Ist der Wert 0, so werden *alle* Cachedateien gelöscht.
- Die cleanup()-Mehode ignoriert alle anderen Dateitypen, die keine Cachedateien sind.
- Leere Verzeichnisse ab dem Cache-Root werden gelöscht.
Seitenanfang
Dokumentation
Class: CacheMethoden verstecken
public __construct($sModule = '.' ,$sCacheID = '.' )constructor
@param string $sModule name of module or app that uses the cache
@param string $sCacheID cache-id (must be uniq for a module; used to generate filename of cachefile)
@return booleanprivate _cleanupDir($sDir ,$iTS ) ... all param(s) requiredrecursive cleanup of a given directory; this function is used by
public function cleanup()
@param string $sDir full path of a local directory
@param string $iTS timestamp
@return trueprivate _getAllCacheData()private function _getAllCacheData() - read cachedata and its meta infos
@return array array with data, file statprivate _getCacheFilename()private function _getCacheFilename() - get full filename of cachefile
@return string full filename of cachefilepublic cleanup($iSec = false )Cleanup cache directory; delete all cachefiles older than n seconds
Other filetypes in the directory won't be touched.
Empty directories will be deleted.
Only the directory of the initialized module/ app will be deleted.
$o=new Cache("my-app"); $o->cleanup(60*60*24*3);
To delete all cachefles of all modules you can use
$o=new Cache(); $o->cleanup(0);
@param int $iSec max age of cachefile; older cachefiles will be deleted
@return truepublic delete()public function delete - delete a single cachefile if it exist
@return booleanpublic dump()public function dump() - dump variables of cache class
@return truepublic getAge()public function getCacheAge() - get age in seconds of exisiting cachefile
@return int age in seconds; -1 if cachefiles does not existpublic getExpire()public function getExpire() - get TS of cache expiration
@return int unix ts of cache expirationpublic getTtl()public function getTtl() - get TTL of cache in seconds
@return int get ttl of cachepublic isExpired()public function isExpired() - cache expired? To check it
you must use ttl while writing data, i.e.
$oCache->write($sData, $iTtl);
@return bool cache is expired?public iExpired()public function iExpired() - get time in seconds when cachefile expires
you must use ttl while writing data, i.e.
$oCache->write($sData, $iTtl);
@return int expired time in seconds; negative if cache is not expiredpublic isNewerThanFile($sRefFile ) ... all param(s) requiredfunction isNewerThanFile($sRefFile) - is the cache (still) newer than
a reference file? This function returns difference of mtime of both
files.
@param string $sRefFile local filename
@return integer time in sec how much the cache file is newer; negative if reference file is newerpublic read()public function getCacheData() - read cachedata if it exist
@return various cachedata or false if cache does not existpublic setData($data ) ... all param(s) requiredpublic function setData($data) - set cachedata into cache object
data can be any serializable type, like string, array or object
Remark: You additionally need to call the write() method to store data in the filesystem
@param various $data data to store in cache
@return booleanpublic setTtl($iTtl ) ... all param(s) requiredpublic function setTtl() - set TTL of cache in seconds
You need to write the cache data to ap
Remark: You additionally need to call the write() method to store a new ttl value with
data in the filesystem
@param type $iTtl ttl value in seconds
@return int get ttl of cachepublic touch()public function touch() - touch cachefile if it exist
For cachedata with a ttl a new expiration will be set
@return booleanpublic write($data = false ,$iTtl = -1 )Write data into a cache.
- data can be any serializable type, like string, array or object
- set ttl in s (from now); optional parameter
@param various $data data to store in cache
@param int $iTTL time in s if content cache expires (min. 0)
@return bool success of write actionProperties verstecken
public $sModule = falsea module name string is used as relative cache path
@var stringpublic $sCacheID = falseid of cachefile (filename will be generated from it)
@var stringprivate $_sCacheDir = falsewhere to store all cache data - it can be outside docRoot. If it is
below docRoot think about forbidding access
If empty it will be set in the constructor to [webroot]/~cache/
or $TEMP/~cache/ for CLI
@var stringprivate $_sCacheFile = falseabsolute filename of cache file
@var stringprivate $_sCacheExt = cacheclass2fileextension for storing cachefiles (without ".")
@var stringprivate $_tsExpire = -1Expiration timestamp;
It will be calculated with current time + ttl in the write() method
TTL can be read with getExpire()
@var integerprivate $_iTtl = -1TTL (time to live) in s;
TTL can be set in methods setTtl($iTtl) or write($data, $iTtl)
TTL can be read with getTtl()
@var integerprivate $_aCacheInfos = falsecachedata and file infos of cachefile (returned array of php function stat)
@var array
Seitenanfang
