Einfaches, dateibasiertes Cachesystem

Wir sammeln alle Infos der Bonusepisode von Pokémon Karmesin und Purpur für euch!

Zu der Infoseite von „Die Mo-Mo-Manie“
  • So, ich hatte wohl LW und dabei kam ein Cachesystem heraus.


    Erstmal:
    Was ist ein "Cachesystem"?
    - Ein Cachesystem ist ein System um häufige aufrufe (zb News auslesen) zu "cachen" d.h. statt sie immer wieder zu berechnen einfach einmal zu berechnen, und das ergebnis zu speichern.


    Was brauche ich?
    - Mittlere kentnisse in PHP5 (OOP empfohlen) und ein Server (virtuell oder nicht ist egal) sollten reichen.


    Warum dateibasiert, und nicht einfach per Datenbank, etc.?
    - Weil mir danach war, und es mir einfacher erschien


    Der Code ist aus einem meiner Projekte gerissen, und somit habe ich alle Abhängigkeiten von meinen anderen klassen auskommentiert und am ende erklärt.
    Ich hab die Kommentare mal in klammern noch übersetzt
    Ihr braucht btw noch einen ordner cache/ mit schreibrechten (chmod 666)


    Cache.class.php

    PHP
    <?php	/**	 * A simple caching engine	 * 	 * @package	miunn.default	 * @author	Mewking	 * @copyright	2011 Miunn	 * @license	GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>	 */	define('BASE_DIR', dirname(__FILE__).'/');	define('NOW', time());	class Cache 	{		/**		 * A unique string which shouldn't be in any var, template etc... (Ein String welcher nicht gecached werden darf)		 */		const NOT_IN_CACHE = '5ej\x118{(r&A+;dn\0gdp(L\x1b\0=wsasSq{KcOj"\x02MP\x11r\0\x1\0bS-0m\x01tf\x17}Z\'Op\0F\x07\x0c;q+\n[0PTJ';		/**		 * Checks whether a var is in cache or not (Prueft ob variable im Cache ist)		 *		 * @param string $cacheId		 * @param integer $expire		 * @return mixed $result		 */		public static function callCache($cacheId, $expire = 30)		{			#MiunnCore::typeHint($cacheId, 'string', 'Cache::callCache', 1);			#MiunnCore::typeHint($expire, 'numeric', 'Cache::callCache', 2);			if ($expire < 0) $expire = 0;			$filename = BASE_DIR.'cache/'.$cacheId.'.cache';			if (file_exists($filename)) {				$content = file_get_contents($filename);				$timestamp = '';				$i = 0;				while (true) {					if (is_numeric(substr($content, $i, 1))) {						$timestamp .= substr($content, $i, 1);					} else {						$i++;						break;					}					$i++;				}				$content = substr($content, $i);				$minMade = NOW - $expire;				if ($timestamp > $minMade) {					return unserialize($content);				} else {					unlink($filename);					return self::NOT_IN_CACHE;				}			} else {				return self::NOT_IN_CACHE;			}		}		/**		 * Writes var to cache		 *		 * @param string $cacheId		 * @param mixed $value		 */		public static function write($cacheId, $value)		{			#MiunnCore::typeHint($cacheId, 'string', 'Cache::callCache', 1);			$filename = BASE_DIR.'cache/'.$cacheId.'.cache';			file_put_contents($filename, NOW.'a'.serialize($value));		}	}?>


    Die Usage ist:

    PHP
    <?php
    	require 'Cache.class.php';
    	$id = 'einzigartigeIDBitteNurZeichenDieAuchInDateinamenKoennen';
    	if (($news = Cache::callCache($id, 60)) === Cache::NOT_IN_CACHE) {
    		$news = '';//Auslesen von News
    		Cache::write($id, $news);
    	}
    	echo $news;
    ?>


    MiunnCore::typeHint()
    prüft auf einen typ und wirft mit exceptions falls es probleme gibt


    /edit: So, alles angepasst^^

  • protected static $unique


    const UNIQUE?


    An sich ist es aber völlig egal was da drin steht, da du bei Explode eh nur 2 Elemente erzeugen läßt und der Timestamp ja keine Daten außer Ziffern enthält ;)


    Btw: dass callCache true zurück gibt, wenn der nichts findet ist ungeschickt, was ist, wenn man true cachen möchte?


  • const UNIQUE?


    An sich ist es aber völlig egal was da drin steht, da du bei Explode eh nur 2 Elemente erzeugen läßt und der Timestamp ja keine Daten außer Ziffern enthält ;)


    Btw: dass callCache true zurück gibt, wenn der nichts findet ist ungeschickt, was ist, wenn man true cachen möchte?


    Das mit der Konstanten scheint mir auch einfacher, danke^^


    Das mit explode dachte ich dass es es so macht:


    $str = 'a.q.f';
    var_dump(explode('.',$str,2)); //array('a', 'qf')


    laut php -a ist das aber wohl doch nicht so :D


    Hm... ich hab für das problem mit dem true schon eine lösung, ich gebe einfach im fehlerfall diesen UNIQUE zurück dann bleibt es bei 2 methoden :D


    Das mit dem explode überarbeite ich gerade^^
    @edit: fertig. Der Timestamp ist nun eine beliebige anzahl an numerischen zeichen bis zum automatisch eingefügten 'a' (Nicht numerischen zeichen).
    Alles danach wird als teil des serialisierten contents gesehen.