Chimicherrychanga

Ein kleiner PHP-Cache

Informatik von Seba

Für große und kleine Optimierungen werden häufig Caches eingesetzt. Im Bereich Weban­wendungen meistens ein File-Cache. Beim ersten Aufruf einer Seite rattert der PHP-Code durch und die erzeugte HTML-Ausgabe wird als Datei gespeichert und ausgegeben. Bei jeder weiteren Anfrage wird dann nur noch auf die Datei zurückgegriffen. Der Gewinn besteht in geringerer Serverbelastung und schnellerer Ausgabe.

Bei meinen Unternehmungen die Datenbank­anfragen zu reduzieren, musste ich die Ergeb­nisse kurzzeitig zwischenspeichern. Ein File-Cache wäre simpler Overkill und ein Datenbank-Cache wäre, nun, dämlich in dem Fall.

Zum Einsatz kommt jetzt eine kleine Klasse, die einfach nur Werte in Variablen speichert und in jedem Scope erreichbar ist. Aufgrund der kurzen Lebensdauer, die nur die Länge einer Seiten-Anfrage hat, heißt die Klasse „RequestCache“.

Implementierung

class RequestCache {
  protected static $store = array();

  public static function save( $key, $value ) {
    self::$store[$key] = $value;
  }

  public static function key_exists( $key ) {
    return array_key_exists( $key, self::$store );
  }

  public static function load( $key ) {
    return self::$store[$key];
  }

  public static function delete( $key ) {
    unset( self::$store[$key] );
  }
}

Kleine Anmerkung: Ich arbeite mit einer statischen Klasse, genauso gut hätte man aber auch ein Singleton nehmen können. Bisher habe ich nichts Überzeugendes gefunden, was für das eine oder andere spräche.

Einsatz in freier Wildbahn

Der Titel einer Seite kann mehrfach benötigt werden: Für das title und die meta tags und natürlich als Überschrift selbst, vielleicht noch irgendwo anders auf der Seite. Das selbe Lied noch einmal mit der Beschreibung. Da ist es doch unsinnig, die Information immer wieder an­zufragen, wenn man sie nach dem ersten Mal doch schon in Händen gehalten hat?

function get_info( $show ) {
  switch( $show ) {

    case 'description':
      if( RequestCache::key_exists( 'description' ) ) {
        return RequestCache::load( 'description' );
      }
      $desc = mysql_fetch_object(
        mysql_query( 'SELECT p_desc, p_title FROM '
            . TABLE_POSTS . ' WHERE post_id = ' . P_ID )
      );
      RequestCache::save( 'title', $desc->p_title );
      RequestCache::save( 'description', $desc->p_desc );
      return $desc->p_desc;

    case 'title':
      if( RequestCache::key_exists( 'title' ) ) {
        return RequestCache::load( 'title' );
      }
      $title = mysql_fetch_object(
        mysql_query( 'SELECT p_desc, p_title FROM '
            . TABLE_POSTS . ' WHERE post_id = ' . P_ID )
      );
      RequestCache::save( 'title', $title->p_title );
      RequestCache::save( 'description', $title->p_desc );
      return $desc->p_title;

  }
}

Wird über die Funktion get_info() die Beschreibung oder der Titel zum ersten Mal abge­fragt, werden beide aus der Datenbank geholt und im Cache gespeichert. Wird ab sofort auch nur eines von beiden abgefragt, wird direkt aus dem Cache bedient und die DB-Anfrage ent­fällt. Von vielleicht 2~6 DB-Anfragen sind wir dann nur noch bei einer. Nett, oder?

Wann man ihn verwendet

Der RequestCache kommt in erster Linie zum Einsatz um Werte zu speichern, die in Funktionen ohne Klassenangehörigkeit verwendet und wahrscheinlich öfter benötigt werden. Auch denkbar ist der Austausch von Informationen zwischen Klassen, damit eine von beiden sich nicht selbst den Wert erst beschaffen muss (wozu sie allerdings die Funktionalität hat!).

Und wann nicht

Nicht verwendet werden sollte er, um ein Objekt in ein anderes hineinzutragen, das dort (als einzige Quelle) Informationen und/oder Funktionalität liefern soll. Stattdessen sollte man das Objekt über eine Methode der Klasse übergeben. Das Konzept wird als Dependency Injection bezeichnet. Ein guter Artikel hierzu: potstuck.com/2009/01/08/php-dependency-injection


Artikel zu Ende! *wirft eine Rauchbombe und verschwindet unter manischem Gelächter*

2 Kommentare

  1. avatar Twaldigas
    Sehr schön und verständlich. Ich habe mich damit leider noch gar nicht beschäftigt, aber dein kleines Tutorial macht Lust auf mehr. Wenn ich nicht so viele andere Sachen hätte, an denen ich momentan sitze. *seufz*
    Ich würde mich auf jeden Fall freuen, viel mehr PHP-Beiträge von dir zu sehen. Wir wäre es denn Mal mit einer Artikel-Reihe, welche OOP erklärt? Nur so ein Gedanke. ;)

    Gruß Twaldigas
  2. avatar Seba
    Mehr PHP-Beiträge? Lässt sich machen. Mindestens zwei habe ich ohnehin noch in Planung*. Wie ich mehr als 1 Artikel mit OOP füllen könnte, weiß ich nicht, aber ich kann mal etwas dazu schreiben, ja. :D

    * Idee vorhanden, geschriebene Wörter: 0

    Edit: Okay, wenn ich so darüber nachdenke, fällt mir doch einiges zu OOP ein, was man in mehrere Teile aufbrechen könnte.

Und jetzt du

Do not fill in these four fields:







Name, Mail und URL sind freiwillige Angaben. E-Mail-Adressen werden weder veröffentlicht noch weitergegeben. Verwendbares HTML: <a href=""> <abbr title=""> <blockquote> <cite> <code> <del> <i> <em> <b> <strong>