0 follower

Cachen von Seitenabschnitten

Das Speichern von Seitenabschnitten (engl.: fragment) bezieht sich auf das Cachen ganzer Bereiche einer Seite. Wenn auf einer Seite z.B. eine Übersicht der Jahresverkäufe in einer Tabelle vorkommt, können wir diese Tabelle im Cache speichern, um die Zeit, die zum Erzeugen dieser Tabelle benötigt wird, einzusparen.

Um Seitenabschnitte zu cachen, rufen wir CController::beginCache() und CController::endCache() im View-Script eines Controllers auf. Die beiden Methoden markieren Anfang und Ende des Seiteninhalts, der gecacht werden soll. Genau wie beim Datencaching müssen wir eine ID vergeben, um den gecachten Seitenabschnitt identifizieren zu können.

...Anderer HTML-Inhalt...
<?php if($this->beginCache($id)) { ?>
...Zu cachender Inhalt...
<?php $this->endCache(); } ?>
...Anderer HTML-Inhalt...

Falls in diesem Beispiel beginCache() false zurückliefert, wird der gecachte Inhalt automatisch an dieser Stelle eingefügt. Andernfalls wird der Inhalt innerhalb der if-Anweisung ausgeführt und gecacht, wenn endCache() aufgerufen wird.

1. Cache-Optionen

Beim Aufruf von beginCache() können wir als zweiten Parameter ein Array mit Cache-Optionen übergeben, um das Cachen von Seitenabschnitten anzupassen. Eigentlich sind die Methoden beginCache() und endCache() nur praktische Wrapper ( sinngem.: Hülle, Umschlag) für das COutputCache-Widget. Die verfügbaren Cache-Optionen entsprechen daher den Eigenschaften von COutputCache.

Dauer

Die wahrscheinlich am häufigsten verwendete Eigenschaft ist duration (Dauer), wodurch bestimmt wird, wie lange der Inhalt im Cache gültig bleibt. Sie ähnelt dem Verfallszeit-Parameter bei CCache::set(). Der folgende Code cacht den Seitenabschnitt für mindestens eine Stunde:

...Anderer HTML-Inhalt...
<?php if($this->beginCache($id, array('duration'=>3600))) { ?>
...Zu cachender Inhalt...
<?php $this->endCache(); } ?>
...Anderer HTML-Inhalt...

Wenn wir die Cache-Dauer nicht angeben, wird ein Vorgabewert von 60 verwendet, was bedeutet, dass der gecachte Inhalt nach 60 Sekunden nicht mehr gültig ist.

Abhängigkeit

Beim Cachen von Seitenabschnitten können, genau wie beim Datencaching, Abhängigkeiten berücksichtigt werden. So kann zum Beispiel der Inhalt eines angezeigten Beitrags davon abhängen, ob der Beitrag verändert wurde.

Um eine Abhängigkeit anzugeben, setzen wir die Option dependency entweder auf ein Objekt, dass das ICacheDependency-Interface implementiert oder auf ein Array das verwendet werden kann, um ein Abhängigkeitsobjekt zu erzeugen. Der folgende Code gibt an, dass der Inhalt des Seitenabschnitts von einer Änderung des Werts in der Spalte lastModified abhängt:

...Anderer HTML-Inhalt...
<?php if($this->beginCache($id, array('dependency'=>array(
        'class'=>'system.caching.dependencies.CDbCacheDependency',
        'sql'=>'SELECT MAX(lastModified) FROM Post')))) { ?>
...Zu cachender Inhalt...
<?php $this->endCache(); } ?>
...Anderer HTML-Inhalt...

Variationen

Gecachter Inhalt kann abhängig von einem bestimmten Parameter variiert werden. Ein Benutzerprofil kann zum Beispiel für verschiedene Benutzer unterschiedlich aussehen. Um den Inhalt des Profils zu cachen, soll die gecachte Kopie entsprechend der Benutzer-ID variieren. Das bedeuted im Wesentlichen, dass wir beim Aufruf von beginCache() unterschiedliche IDs verwenden sollten.

Statt vom Entwickler zu erwarten, IDs nach einem bestimmten Schema zu variieren, hat COutputCache ein solches Feature schon eingebaut. Hier eine Übersicht:

  • varyByRoute: Wenn diese Option auf true gesetzt wird, wird der gecachte Inhalt entsprechend der Route variiert. Dadurch führt jede Kombination aus angefordertem Controller und Action zu einem anderen Cache-Inhalt.

  • varyBySession: Wenn diese Option auf true gesetzt wird, wird der gecachte Inhalt entsprechend der session ID variiert. Dadurch kann für jede Benutzer-Session unterschiedlicher Inhalt angezeigt werden, der jeweils vom Cache geliefert wird.

  • varyByParam: Wenn diese Option auf true gesetzt wird, wird der gecachte Inhalt entsprechend den Werten der angegebenen GET-Parameter variiert. Wenn eine Seite z.B. einen Beitrag entsprechend dem GET-Parameter id anzeigt, können wir varyByParam auf array('id') setzen, so dass der Inhalt jedes Beitrags gecacht wird. Ohne diese Variation könnten wir nur einen einzelnen Beitrag cachen.

  • varyByExpression: Indem diese Option auf einen PHP-Ausdruck gesetzt wird, kann der geachte Inhalt entsprechend dem Ergebnis dieses Ausdrucks variiert werden. Diese Option steht seit Version 1.0.4 zur Verfügung.

Request-Typen

Manchmal möchten wir das Cachen von Seitenabschnitten nur für bestimmte Request-Typen verwenden. Bei einer Seite, die ein Formular anzeigt, soll dieses z.B. nur beim ersten Request (per GET-Request) gecacht werden. Bei allen weiteren Anfragen (per POST-Request) soll das Formular nicht gecacht werden, weil es evtl. Benutzereingaben enthält. Um dies zu erreichen, können wir die Option requestTypes verwenden:

...Anderer HTML-Inhalt...
<?php if($this->beginCache($id, array('requestTypes'=>array('GET')))) { ?>
...Zu cachender Inhalt...
<?php $this->endCache(); } ?>
...Anderer HTML-Inhalt...

2. Verschachteltes Cachen

Gecachte Seitenabschnitte können auch verschachtelt werden. Das bedeutet, dass ein gecachter Seitenabschnitt in einem größeren, ebenfalls gecachten Seitenabschnitt eingebettet ist. Z.B. könnten Kommentare in einem inneren Seitenabschnitt gecacht werden und gemeinsam mit dem Beitragsinhalt in einem äußeren Seitenabschnitt.

...other HTML content...
<?php if($this->beginCache($id1)) { ?>
...Äußerer zu cachender Inhalt...
    <?php if($this->beginCache($id2)) { ?>
    ...Innerer zu cachender Inhalt...
    <?php $this->endCache(); } ?>
...Äußerer zu cachender Inhalt...
<?php $this->endCache(); } ?>
...Anderer HTML-Inhalt...

Auf die verschachtelten Caches können unterschiedliche Optionen angewendet werden. Z.B. können oben der innere und äußere Cache jeweils verschiedene Werte für die Cache-Dauer verwenden. Wenn die Daten im äußeren Cache für ungültig erklärt werden, kann der innere immer noch einen gültigen Seitenabschnitt liefern. Allerdings gilt das nicht umgekehrt. Falls der äußere Cache noch gültige Daten enthält, wird er immer die gecachte Kopie ausliefern, selbst wenn die Daten des inneren Cache bereits abgelaufen sind.