Zend Framework Tutorial Teil 10: Sinnvoll cachen mit Zend_Cache

Im neunten Teil vom Zend Framework Tutorial haben wir die Zend_Filter Komponente für das Filtern von Benutzereingaben kennen und anwenden gelernt. Zudem hast du in einer umfangreicheren Übung (so hoffe ich zumindest) die Kommentarfunktion für unser TravelloBlog realisiert. Wenn du die ersten neun Teile noch nicht gelesen hast, hole dies bitte schnell nach.

In diesem zehnten Teil des Zend Framework Tutorials werde ich Dir die Komponente Zend_Cache vorstellen, mit der du beliebige Daten cachen kannst. Dabei werden wir uns um das Cachen von Templates sowie Datenbankabfragen kümmern und so die Performance unseres TravelloBlogs stark verbessern.

Wenn du über neue Tutorial Teile informiert werden möchtest, abonniere am besten den Feed dieses Blogs. Dann verpasst du garantiert keinen Teil des Tutorials.

Wichtig: Dieses Tutorial setzt die Zend Framework Preview Version 0.2.0 voraus und kann bei der Verwendung einer aktuelleren Version aus dem SVN unter Umständen nicht zu 100% funktionieren.

Inhaltsverzeichnis

Zend_Cache

Zum Einstieg empfehle ich wie immer als ersten den Blick in das Zend_Cache Kapitel im Manual, in dem die Verwendungsmöglichkeiten von Zend_Cache umfassend beschrieben ist.

Bei der Verwendung von Zend_Cache ist zuallererst zwischen dem Frontend und dem Backend zu unterscheiden. Die Zend_Cache Frontends kümmern sich darum, was gecached werden soll, während sich die Zend_Cache Backends darum kümmern, wie gecached werden soll.

Zend_Cache bietet von Haus aus bereits Frontends für das Cachen von Ausgaben, Funktionen, Objekten, Dateien und kompletten Seiten. Dadurch ist Zend_Cache sehr flexibel gestaltet, so dass du dich nicht nur auf das Cachen von Templates beschränken musst, sondern auch Klassen, Datenbankabfragen oder dynamisch erstellte Dateien bequem cachen kannst.

Auch beim Backend bietet Zend_Cache mehrere Optionen. So können die gecacheden Daten als Dateien, in einer Sqlite Datenbank, in einem Memcache Server oder im Shared Memory gespeichert werden. Während für einige Fällen das Cachen in Dateien sinnvoll und ausreichend ist, wäre in anderen Fällen wiederum das Cachen im Shared Memory sinnvoller.

Für weitere Details empfehle ich noch mal den Blick ins Manual, da das Kapitel über Zend_Cache recht umfangreich ist. Da es dort auch viele Beispiele gibt, spare ich mir diese an dieser Stelle. Nach einigen Vorüberlegungen steigen wir eh gleich direkt in die Anwendung ein.

Vorüberlegungen

Als erstes überlegen wir einmal, welche Daten wir überhaupt sinnvoller Weise cachen wollen. Wenn wir das entschieden haben, machen wir uns darüber Gedanken, wie wir diese Daten cachen möchten.

Als erster Anwendungsfall kommt dir sicherlich das Cachen der Ausgaben, also der Templates in den Sinn. Als Frontend würde sich dafür Zend_Cache_Frontend_Output und als Backend Zend_Cache_Backend_File anbieten.

Ein weitere Anwendungsfall wären Datenbankabfragen, die auf jeder bzw. auf sehr vielen Seiten unseres TravelloBlogs durchgeführt werden. Da würden sich z.B. die Datenbankabfragen für die Navigation oder unsere Tagwolke anbieten. Als Frontend würden sich hierfür Zend_Cache_Frontend_Core anbieten und als Backend würde ich wieder Zend_Cache_Backend_File wählen.

Um unsere Cache Dateien speichern zu können, benötigen wir ein weiteres Verzeichnis. Lege also bitte das Verzeichnis "/public/tmp" an und platziere dort eine .htaccess Datei mit folgendem Inhalt, um eine direkten Aufruf der Cache Dateien über den Browser zu vermeiden:

deny from all

Es macht Sinn, das Verzeichnis auch in unsere "settings.ini" Datei aufzunehmen, damit wir über unser Zend_Config Objekt überall darauf zugreifen können. Deshalb füge in die "settings.ini" noch folgenden Eintrag für das Cache Verzeichnis hinzu:

framework.cache_dir       = e:\travelloblog\public\tmp

Startseite cachen

Als erstes benötigen wir ein Zend_Cache Objekt für das Speichern der Templates in Dateien. Dazu öffne die Datei "settings.php" im Verzeichnis "/application/config" und füge dort folgenden Code ans Ende an.

PHP:
  1. <?php
  2. [...]
  3.  
  4. $frontendOptions = array('lifeTime' => 10);
  5. $backendOptions = array('cacheDir' => $config->framework->cache_dir);
  6. $templateCache = Zend_Cache::factory('Output', 'File', $frontendOptions, $backendOptions);
  7. Zend::register('templateCache', $templateCache);
  8. ?>

Wir erstellen also einen Cache unter Verwendung des "Output" Frontends und des "File" Backends. Als Parameter für das Frontend habe ich eine Lebenszeit für den Cache von 10 Sekunden angegeben. Auf einem Produktiv Server sollte dieser Wert natürlich höher gesetzt werden. An das Backend übergeben wir nur das erstellte Cache Verzeichnis.

Hinweis

Natürlich kannst du die Angaben zum Frontend und Backend sowie deren Optionen auch in unserer zentralen Konfigurationsdatei "settings.ini" verwalten und dann beim Aufruf von Zend_Cache::factory() übergeben. Ich habe darauf an dieser Stelle einfach verzichtet.

Widmen wir uns nun dem Cachen unserer Startseite, die wohl am häufigsten aufgerufen werden wird. Öffne also bitte den die Datei "ArticleController.php" und suche dort nach der Methode indexAction. Diese änderst du nun wie folgt ab:

PHP:
  1. <?php
  2.     [...]
  3.  
  4.     public function indexAction()
  5.     {
  6.         $this->_cacheId = 'index';
  7.        
  8.         if (!$this->_cacheTpl = Zend::registry('templateCache')->get($this->_cacheId))
  9.         {
  10.             $article = new ArticleModel();
  11.            
  12.             $order  = 'art_cdate DESC';
  13.             $rowset = $article->fetchAll(null, $order);
  14.            
  15.             $data = $rowset->toArray();
  16.            
  17.             $this->_view->assign('title', 'TravelloBlog - List of articles');
  18.             $this->_view->assign('articles', $data);
  19.             $this->_view->assign('subtemplate', 'article/index.php');
  20.         }
  21.     }
  22.  
  23.     [...]
  24. ?>

Als erstes legen wir eine Cache Id fest, unter der unser Template gecached werden soll. Wir speichern diese Cache Id in der Klasseneigenschaft $this->_cacheId ab, damit wir später noch darauf zugreifen können.

Danach versuchen wir die Cache Datei für diese Cache Id zu lesen und in der Klasseneigenschaft $this->_cacheTpl abzulegen. Wenn keine gültige Cache Datei gefunden werden konnte, wird false zurückgegeben und die weiteren Zeilen in der if-Bedingung werden ausgeführt. Falls eine gültige Cache Datei gefunden werden konnte, wird dieser Teil nicht ausgeführt. Das war es auch schon im ArticleController für die Startseite.

Wie du dich sicher noch erinnern kannst, haben wir die Ausgabe unsere Templates an eine zentrale Stelle ausgelagert. Und zwar in den Destruktor unserer Travello_Controller_Action Klasse. Als öffne bitte die Datei "Action.php" im Verzeichnis "/library/zf/Travello/Controller/". Der Vollständigkeit halber erstellen wir zuerst die beiden in der indexAction Methode vom ArticleController verwendeten Klasseneigenschaften $this->_cacheId und $this->_cacheTpl und ändern die Methode __destruct wie folgt ab:

PHP:
  1. <?php
  2. abstract class Travello_Controller_Action extends Zend_Controller_Action
  3. {
  4.     [...]
  5.  
  6.     protected $_cacheTpl = false;
  7.    
  8.     protected $_cacheId = false;
  9.    
  10.     protected $_cacheTag = array();
  11.    
  12.     [...]
  13.  
  14.     public function __destruct()
  15.     {
  16.         if (!$this->_cacheTpl)
  17.         {
  18.             $this->_view->assign('navigation', $this->getNavigation());
  19.             $this->_view->assign('tagcloud', $this->getTagcloud());
  20.             $this->_view->assign('lastcomments', $this->getComments());
  21.            
  22.             $this->_cacheTpl = $this->_view->render($this->_template);
  23.            
  24.             if ($this->_cacheId)
  25.             {
  26.                 Zend::registry('templateCache')->save($this->_cacheTpl, $this->_cacheId, $this->_cacheTag);
  27.             }
  28.         }
  29.        
  30.         echo $this->_cacheTpl;
  31.     }
  32. }
  33. ?>

Zuerst wird anhand von $this->_cacheTpl geprüft, ob keine Cache Datei gelesen werden konnte. Falls nicht werden die weiteren Templatevariablen zugeordnet sowie die Ausgabe des Templates an $this->_cacheTpl übergeben.

Danach wird geprüft, ob eine Cache Id gesetzt worden ist und bei Bedarf wird das Template in der Cache Datei für unsere angegebene Cache Id gespeichert. Zum Schluss kann dann einfach $this->_cacheTpl ausgegeben werden, weil dort entweder die gelesenen Cache Daten oder das eben gerenderte Template enthalten ist.

Hinweis

Die bereits eingeführte, aber noch nicht erläuterte Klasseneigenschaft $this->_cacheTag benötigen wir an dieser Stelle eigentlich noch nicht. Der Sinn wird erst im nächsten Abschnitt erläutert.

Bevor wir uns das Ergebnis nun anschauen können, solltest du noch in deinem Haupttemplate einen Zeitstempel einbauen, damit man auch sehen kann, ob das Cachen wirklich geklappt hat. Also öffne die Datei "main.php" im Verzeichnis "/application/views" und ändere den Footer wie folgt ab:

PHP:
  1. [...]
  2. <div id="footer">
  3. TravelloBlog 2006 - Last update: <?php echo date('Y-m-d H:i:s'); ?>
  4. </div>
  5. [...]

Danach rufe die Startseite des TravelloBlogs auf. Du siehst unten den Zeitstempel und wenn du die Startseite vor Ablauf der 10 Sekunden erneut aufrufst, sollte sich der Zeitstempel nicht verändert haben. Alle anderen Seiten werden aber noch nicht gecached.

Artikelseite cachen

Durch den Destruktor in unserer Travello_Controller_Action Klasse und durch die beiden Klasseneigenschaften $this->_cacheTpl und $this->_cacheId ist das Einführen des Cachens in allen anderen Aktionsmethoden unserer Controller nur noch ein Kinderspiel. Wir müssen lediglich eine Cache ID festlegen und die Abfrage der Cache Datei einbauen.

Für das Cachen eines Artikels macht es Sinn, in die Cache Id auch die Id des Artikels zu übernehmen. Ändere also als nächstes die showAction Methode im ArticleController wie folgt ab:

PHP:
  1. <?php
  2.     [...]
  3.  
  4.     public function showAction()
  5.     {
  6.         $art_id = $this->_getParam('id');
  7.        
  8.         $this->_cacheId = 'article_show_' . $art_id;
  9.        
  10.         $this->_cacheTag = array('article_' . $art_id);
  11.        
  12.         if (!$this->_cacheTpl = Zend::registry('templateCache')->get($this->_cacheId))
  13.         {
  14.             $article = new ArticleModel();
  15.  
  16.             [...]
  17.         }
  18.     }
  19.  
  20.     [...]
  21. ?>

Wir erstellen also als erstes eine Cache Id, indem wir die aktuelle Artikel Id anhängen. Danach wird wieder versucht, eine gültige Cache Datei zu lesen. Schlägt dies fehl, werden die notwendigen Daten gelesen. Um den Rest, also das Rendern des Templates und das Speichern in einer Cache Datei kümmert sich dann wieder der Destruktor in unserer Travello_Controller_Action Klasse.

An dieser Stelle haben wir nun die Klasseneigenschaft $this->_cacheTag belegt und du fragst dich sicherlich nach dem Sinn. Mit Hilfe von so genannten Cache Tags kannst du bestimmte Cache Dateien auszeichnen, um sie später gezielt löschen zu können. Es macht also Sinn, alle Cache Dateien eines Artikels zu löschen, wenn sich dieser Artikel ändert oder wenn er gelöscht wird. Darum kümmern wir uns gleich im nächsten Abschnitt.

Die selben Änderungen führen wir nun auch für die Aktionsmethoden deleteAction durch, welche einen Artikel vor dem Löschen noch einmal zur Kontrolle anzeigt. Auch hier setzen wir den gleichen Cache Tag.

PHP:
  1. <?php
  2.     [...]
  3.  
  4.     public function deleteAction()
  5.     {
  6.         $art_id = $this->_getParam('id');
  7.        
  8.         $this->_cacheId = 'article_delete_' . $art_id;
  9.        
  10.         $this->_cacheTag = array('article_' . $art_id);
  11.        
  12.         if (!$this->_cacheTpl = Zend::registry('templateCache')->get($this->_cacheId))
  13.         {
  14.             $article = new ArticleModel();
  15.  
  16.             [...]
  17.         }
  18.     }
  19.  
  20.     [...]
  21. ?>

Das war es auch schon. Mehr Aktionsmethoden im ArticleController benötigen kein Cachen, da es keinen Sinn macht, Formulare zu cachen.

Cache Dateien löschen

Unter bestimmten Voraussetzungen macht es Sinn, bestehende aber noch nicht ungültige Cache Dateien zu löschen. Zur Demonstration ändere bitte einmal die Cache Lebenszeit in der "settings.php" Datei von 10 auf 20 Sekunden. Lasse dir dann einen Artikel anzeigen und füge einen Kommentar hinzu. Es sieht nun so aus, als wenn der Kommentar nicht gespeichert worden wäre.

Als müssen wir nach der Änderung eines Artikels oder nach dem Hinzufügen eines Kommentars alle Cache Dateien für diesen Artikel löschen. Hierbei kommt nun endlich auch der Cache Tag zur Anwendung.

Öffne also nun den CommentController und füge in der saveData Methode vor dem Redirect folgende Zeile ein:

PHP:
  1. <?php
  2.     [...]
  3.  
  4.     private function saveData($data)
  5.     {
  6.         [...]
  7.        
  8.         Zend::registry('templateCache')->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('article_' . $art_id));
  9.         Zend::registry('templateCache')->remove('index');
  10.        
  11.         $url = getRewriteBase() . '/article/show/' . $art_id;
  12.        
  13.         $this->_redirect($url);
  14.     }
  15.  
  16.     [...]
  17. ?>

In der ersten Zeile holen wir uns das Cache Objekt aus dem Objektspeicher, rufen die clean() Methode auf und übergeben den Löschmodus für das Löschen anhand von Tags sowie den Tag selber. In der zweiten neuen Zeile löschen wir den Cache für die Startseite anhand der eindeutigen Cache Id.

Wenn du nun erneut einen Artikel aufrufst und einen Kommentar hinzufügst, wird dieser sofort angezeigt.

Beide Zeilen musst du nun noch in der doDeleteAction Methode vom CommentController hinzufügen, damit auch beim Löschen eines Kommentars der Cache gelöscht wird.

PHP:
  1. <?php
  2.     [...]
  3.  
  4.     private function doDeleteAction()
  5.     {
  6.         [...]
  7.        
  8.         $art_id = $row->comArtId;
  9.        
  10.         Zend::registry('templateCache')->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('article_' . $art_id));
  11.         Zend::registry('templateCache')->remove('index');
  12.        
  13.         $url = getRewriteBase() . '/article/show/' . $art_id;
  14.        
  15.         $this->_redirect($url);
  16.     }
  17.  
  18.     [...]
  19. ?>

Der Vollständigkeit halber müssen wir nun auch im ArticleController noch die Cache Dateien nach der Änderung eines Artikels bzw. nach dem Löschen eines Artikels entfernen. Also füge die beiden Zeilen ebenfalls im ArticleController in den Methoden saveData und doDeleteAction vor dem Redirect ein.

Datenbankabfragen cachen

Jetzt möchten wir noch einen anderen Anwendungsfall betrachten. Und zwar werden bestimmte Datenbankabfragen auf jeder Seite durchgeführt. Dabei handelt es sich um das Lesen der Kategorien für die Navigation, um die Tagwolke und die letzten Kommentare. Es macht durchaus Sinn, diese Daten auch zu cachen, da wir sie sicher nicht bei jedem Seitenabruf neu laden müssen.

Dafür benötigen wir als erstes ein weiteres Cache Objekt, mit dem wir Methodenaufrufe einer Klasse cachen können. Füge also am Ende der "settings.php" Datei folgende Zeilen ein:

PHP:
  1. <?php
  2. [...]
  3.  
  4. $frontendOptions = array('lifeTime' => 20, 'automaticSerialization' => true);
  5. $backendOptions = array('cacheDir' => $config->framework->cache_dir);
  6. $dataCache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
  7. Zend::register('dataCache', $dataCache);
  8. ?>

Wir setzen hier die automatische Serialisierung der Daten auf true, damit wir ohne größeren Aufwand auch Arrays speichern können. Die Lebenszeit können wir deutlich höher setzen als bei den Templates, da sich die zu cachenden Daten wie Kategorien meistens noch seltener ändern.

Danach ändere bitte in der Datei "Action.php" im Verzeichnis "/library/zf/Travello/Controller/" die Methode "getNavigation" wie folgt ab:

PHP:
  1. <?php
  2.     [...]
  3.  
  4.     private function getNavigation()
  5.     {
  6.         $cacheId = 'data_navigation';
  7.        
  8.         if (!$data = Zend::registry('dataCache')->get($cacheId))
  9.         {
  10.             $category = new CategoryModel();
  11.            
  12.             $order  = 'cat_name';
  13.             $rowset = $category->fetchAll(null, $order);
  14.            
  15.             $data = $rowset->toArray();
  16.            
  17.             Zend::registry('dataCache')->save($data, $cacheId);
  18.         }
  19.        
  20.         return $data;
  21.     }
  22.  
  23.     [...]
  24. ?>

Wir legen wieder eine Cache Id fest und prüfen, ob es eine gültige Cache Datei gibt. Falls nicht, werden die Daten aus der Datenbank gelesen und im Cache gespeichert. Das war es auch schon.

Der Vollständigkeit halber hier die Änderungen für die Methode "getTagcloud":

PHP:
  1. <?php
  2.     [...]
  3.  
  4.     private function getTagcloud()
  5.     {
  6.         $cacheId = 'data_tagcloud';
  7.        
  8.         if (!$tags = Zend::registry('dataCache')->get($cacheId))
  9.         {
  10.             $tag = new TagModel();
  11.             $db = $tag->getAdapter();
  12.            
  13.             $select = $db->select();
  14.             $select->from('tag', 'tag.*, COUNT(tag_id) AS tag_count');
  15.             $select->join('art2tag', 'tag_id = art2tag_tag_id');
  16.             $select->order('tag_name');
  17.             $select->group('tag_id');
  18.            
  19.             $tags = $db->fetchAll($select);
  20.            
  21.             Zend::registry('dataCache')->save($tags, $cacheId);
  22.         }
  23.                
  24.         return $tags;
  25.     }
  26.  
  27.     [...]
  28. ?>

Und hier die Änderungen für die Methode "getComments":

PHP:
  1. <?php
  2.     [...]
  3.  
  4.     private function getComments()
  5.     {
  6.         $cacheId = 'data_lastcomments';
  7.        
  8.         if (!$comments = Zend::registry('dataCache')->get($cacheId))
  9.         {
  10.             $comment = new CommentModel();
  11.             $db = $comment->getAdapter();
  12.            
  13.             $select = $db->select();
  14.             $select->from('comment', '*');
  15.             $select->order('com_date DESC');
  16.             $select->limit(5);
  17.            
  18.             $comments = $db->fetchAll($select);
  19.            
  20.             Zend::registry('dataCache')->save($comments, $cacheId);
  21.         }
  22.                
  23.         return $comments;
  24.     }
  25.  
  26.     [...]
  27. ?>

Soviel erst einmal zur Zend_Cache Komponente, die auch noch viele weitere Anwendungsmöglichkeiten bietet. Zum Beispiel könnten wir unser Zend_Config Objekt auch in einer Cache Datei ablegen usw.

Übung: Caching für weitere Controller

Als heutige Übung nehme dir bitte den TagController und den CategoryController vor und füge dort auch die Caching Funktionalität hinzu. Achte dabei auch darauf, dass du bei Änderungen alte Cache Dateien löscht. Zudem musst du natürlich auch die Anzeige der 404 Fehlerseite im IndexController cachen. Achte hier aber auf die Ausgabe des 404 Status, der immer ausgegeben werden muss.

Zur Kontrolle lade dir den aktuellen Stand des Tutorials runter. Dann kannst du deine Ergebnisse damit vergleichen.

Download

Der aktuelle Stand des Tutorials nach diesem sechsten Teil kann herunter geladen werden. Hier sind auch alle Templates enthalten. Die Textdateien "empty.txt" in einigen Verzeichnissen habe ich nur angelegt, weil mein Winzip keine leeren Verzeichnisse im Zip Archiv anlegt:

Die Zip Datei enthält nicht die aktuelle Version des Zend Frameworks. Dies musst du bitte selber in das entsprechende Verzeichnis kopieren.

Zusammenfassung

In diesem zehnten Teil des Zend Framework Tutorials haben wir die Zend_Cache Komponente kennen gelernt und unsere erstellten Templates in Cache Dateien gespeichert. Wir haben uns außerdem darum gekümmert, dass Cache Dateien von Artikeln auch gelöscht werden, wenn es neue Kommentare gibt oder der Artikel geändert wird. Zudem haben wir einige Datenbankabfragen gecached, um die Datenbank zu entlasten.

Im nächsten Teil des Tutorials werde ich dir die nützlichen Komponenten Zend_Log für das Erstellen von individuellen Logs sowie Zend_Mail für den Versand von E-Mails vorstellen.

Change Log

An dieser Stelle werden Änderungen an diesem Tutorial Teil zusammengefasst, die nach dem Ersterscheinen (23.10.2006) notwendig waren, z.B. durch neuere Versionen des Zend Frameworks oder Änderungen am Konzept des Tutorials oder den Anforderungen an unser TravelloBlog.

  • 05.11.2006: Tutorial für Release 0.2.0 aktualisiert

Navigation

13 Antworten für “Zend Framework Tutorial Teil 10: Sinnvoll cachen mit Zend_Cache”

  1. Ralfs PHP Blog » Zend Framework Tutorial Teil 9: Benutzereingaben filtern mit Zend_Filter_Input sagt:

    [...] Framework, Zend Framework Tutorial, Zend Filter, Zend Filter Input Bookmark: del.icio.us yigg.de mister-wong.de  [...]

  2. Dino sagt:

    Ehm soweit so gut,
    ich verwende smarty und ansich klappt es natürlich auch ohne Probleme. Aber ich habe auch in einem Formular was gecachet werden soll einen dynamischen Teil (Captcha). Was wär die sinnvollste Art, dies trotz Cachen immer richtig aktualisiert (das Bild) anzeigen zu lassen.

    Gruß

  3. Daniel Lonn sagt:

    Etwas was vielleicht mehr mit dem Zend Framework als mit dem Tutorial zu tun hat, Bei manchen Providern bekomme ich bei Aufruf des Beispiels folgenden Error:

    "Fatal error: Ignoring exception from [Controller-Name]::__destruct() while an exception is already active in /[Path-to-Zend]/Controller/Dispatcher.php on line 137"

    Die RewriteEngine funktioniert, Php5 läuft und die DB-Zugangsdaten sind jeweils auch korrekt.

    Naja, falls jemand ähnliches mal gelöst haben sollte oder einen Hinweis zur Interpretation zu "exception is already active" hat wäre ich dankbar..

    Gruss - Daniel

  4. Daniel Lonn sagt:

    Die Testumgebung brachte erstmal Licht ins Dunkle:
    'The pgsql driver is not currently installed', also wenn beim Server kein entsprechender PDO-Treiber installiert ist läuft halt nichts.
    Zend Framework ist also unschuldig..

  5. Ralf Eggert sagt:

    @Daniel

    ja manchmal sind Probleme auf den ersten Blick nicht zu erkennen. Ich denke spätestens mit der Version 1.0 werden dann die Anforderungen des Zend Frameworks an den Server genau festgelegt sein. Dann kann man sicher eine Art Checkliste abarbeiten und findet es schneller, wenn was fehlt.

    Gruß,

    Ralf

  6. Ralf Eggert sagt:

    @Dino

    generell denke ich, dass das Cachen von Formularen etwas schwieriger zu handeln ist. Man kann zwar den Rohzustande eines leeren Formulars cachen, aber schon nach dem ersten Absenden (wenn das Formular erneut angezeigt werden soll), könnte es Schwierigkeiten geben.

    Wenn du sowieso Smarty verwendest, würde ich dann auch die Caching Funktionen von Smarty verwenden. Da gibt es die Möglichkeit, per {insert} Bereiche auf einer zu cachenden Seite zu definieren, die nicht gecached werden sollen.

    http://smarty.php.net/manual/de/language.function.insert.php

    Gruß,

    Ralf

  7. Dino sagt:

    Hallo,

    danke erstmal. Aber so einfach wie ich es mir gedacht habe ist es auch nicht. Denn meine Funktion erstellt erst dann ein neues Captcha, wenn der Cache alle 10Sekunden erneuert wird. Ich weiß jetzt nicht wie ich weiter machen soll, da es ziemlich schwierig ist...

  8. Ralf Eggert sagt:

    Hallo Dino,

    ich würde wie gesagt für Formulare gar kein Caching einsetzen.

    Hast du es denn einmal mit der {insert} Funktion von Smarty probiert?

    Gruß,

    Ralf

  9. Ralfs PHP Blog » Zend Framework Tutorial Teil 11: Nützliche Komponenten Zend_Log und Zend_Mail sagt:

    [...] Im zehnten Teil vom Zend Framework Tutorial haben wir die Zend_Cache Komponente für das Cachen von Templates und Datenbankabfragen kennen gelernt und in unser Projekt integriert. Wenn du die ersten zehn Teile noch nicht gelesen hast, hole dies bitte schnell nach. [...]

  10. Dino sagt:

    Hi,

    ja ich habe es mal versucht. Nur wenn ich via modifiziertem Action Controller (siehe Tutorial) mein Template ausgebe, muss ich dort erst die Funktion function insert_foo() erstellen, was schonwieder total unübersichtlich wird. Zudem kommt noch hinzu, dass ich mein Captcha dann auch nur alle 10Seks neu erstellen würde, da er ja bei Smartycache den Inhalt nur dann ausführt wenn die 10Seks rum sind/keine Cacheversion vorliegt. Somit wäre das Captcha total sinnlos, wenn jemand z.B. 2 mal auf den Artikel klickt. Ich hoffe du weißt was ich mein^^ Dann bliebe nurnoch der Verweis "Neuen Kommentar erstellen" unter den einzelnen Kommentaren. Oder hast du noch eine andere Idee?

    Gruß

  11. Ralfs PHP Blog » Zend Framework Tutorial Teil 1: Einführung und Anforderungen sagt:

    [...] Sinnvoll cachen mit Zend_Cache [...]

  12. Ralf Eggert sagt:

    Hallo Dino,

    tut mir leid, da fällt mir momentan auch nichts besseres ein. :-(

    Gruß,

    Ralf

  13. Michel Feldheim sagt:

    Danke für die Tipps und Ideen - die Abhandlung im Destruktor ist eine relativ gute Idee, allerdings etwas unsauber, da eventuelle Exceptions die oft zitierte Fehlermeldungen

    "Fatal error: Ignoring exception from [Controller-Name]::__destruct() while an exception is already active[..]"
    oder
    "Fatal error: Exception thrown without a stack frame in Unknown on line 0"

    forcieren.
    Es ist nicht erlaubt, Exceptions im Destruktor zu werfen.

Hinterlasse eine Antwort