Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Geleitwort des Fachgutachters
Vorwort
1 Einleitung
2 Einführung in eZ Components
3 Die Applikationsbasis
4 Fehlerbehandlung und Debugging
5 Konfiguration
6 Datenbankanbindung
7 ORM mit PersistentObject
8 Template
9 Übersetzung
10 Benutzereingaben validieren
11 Authentifizierung
12 Bildverarbeitung
13 Archive und Dateien
14 Mail
15 Logging
16 Diagramme
17 Feeds und Caching
18 Setup
A Inhalt der Buch-CD
Stichwort
Download: - ZIP, ca. 2,7 MB
Ihre Meinung?
<< zurück | Galileo Computing / <openbook> /eZ Components | vor >>
eZ Components von Tobias Schlitt, Kore Nordmann Das Entwickler-Handbuch
eZ Components geb., mit CD 454 S., 39,90 Euro Galileo Computing ISBN 978-3-8362-1073-7 |
| 17 Feeds und Caching
|  | 17.1 Feed
|  |  | 17.1.1 Feeds parsen
|  |  | 17.1.2 Feeds erzeugen
|  | 17.2 Die Cache-Komponente
|  |  | 17.2.1 Motivation
|  |  | 17.2.2 Architektur
|  |  | 17.2.3 Praktisches
|  | 17.3 Cache-Attribute
|  | 17.4 Fazit
## 17.2 Die Cache-Komponente Während sich der letzte Abschnitt mit der sich noch im Beta-Stadium befindlichen Komponente Feed beschäftigt hat, lernen Sie nun die Cache-Komponente kennen. Mit ihrer Hilfe wird die Ausgabe von Feeds zwischengespeichert. ### 17.2.1 Motivation Das Ziel von Caching ist, die Performance einer Applikation zu steigern, ohne in Hardware zu investieren. Performance meint an dieser Stelle die Menge an Anfragen, die pro Intervall bearbeitet werden kann, sowie die Menge an Benutzern, die parallel mit einer Anwendung arbeiten können. Ohne näher auf Caching-Strategien einzugehen, wollen wir hier anhand eines fiktiven Beispiels die Idee des Verfahrens erläutern. Die Idee hinter einer dynamischen Webseite sowie hinter jeder Art von Webanwendung ist die Bereitstellung von automatisch generierten Inhalten. Inhalte beschreiben hier eine schier unüberschaubare Menge an Informationen der unterschiedlichsten Kategorien: Aktienkurse direkt aus dem Rechner der Börse, aktuelle Nachrichten des lokalen Radiosenders oder die Termine der Schulband sind nur einige Beispiele. Aus der Dynamik der Daten folgt direkt die Anwendung einer Programmiersprache, um die Veröffentlichung zu automatisieren und die Pflege der Daten zu vereinfachen. Caching geht diesen Weg – zumindest in Teilen – wieder zurück, um das System zu entlasten. Zwar handelt es sich bei den durch eine Webanwendung bereitgestellten Daten um dynamisch generierte Informationen, doch ändern sich diese zwischen zwei Requests sehr häufig nicht. Oft noch nicht einmal über einen längeren Zeitraum. Ziel ist es nun, den bereitgestellten Inhalt in sinnvolle Sektionen zu unterteilen. Im GP-Blog tun wir dies, indem die Bereitstellung eines Feeds von den anderen Bereichen abgegrenzt wird. Meist werden Sie Ihre Anwendung jedoch viel feinschichtiger analysieren. Haben Sie diejenigen Einheiten identifiziert, deren Inhalt sich selten ändert, die aber dennoch ständig neu generiert werden, so gilt es, diese vom Darstellungsprozess Ihrer Anwendung abzuspalten und nur bei Bedarf zu generieren. Ansonsten werden die bereits generierten und statisch gespeicherten Daten ausgeliefert. Zwei kleine Gedankenspiele sollen verdeutlichen, wie unterschiedlich Caching angewendet werden kann und wie breit das Spektrum der Wirkung ist. Das erste Beispiel soll der hier gezeigte Code zur Generierung des RSS-Feeds sein. Die Generierung des RSS-Feeds erfordert nicht viel Arbeit. Eine SQL-Query wird abgesetzt, die nach einfachen Kriterien 20 Einträge lädt. Anschließend werden diese Informationen in eine neue Objektstruktur kopiert und ausgegeben. ### 17.2.2 Architektur Die Cache-Komponente besteht aus zwei Schichten: Dem Cache-Manager in der Klasse ezcCacheManager und den von ihm verwalteten Handler-Klassen, welche die abstrakte Klasse ezcCacheStorage erweitern. #### Backend-Handler Die Klasse ezcCacheStorage legt das öffentliche Interface der Cache-Backend-Handler fest. Die drei wichtigsten Methoden – store() zum Speichern von Informationen, restore() für das Wiederherstellen von Informationen und delete() zum Entfernen von Informationen – werden hier abstrakt beschrieben. Alle drei Basismethoden arbeiten mit zwei Identifikationsmechanismen für Cache-Inhalte. Jedes Cache-Item besitzt eine eindeutige ID und wird durch eine Menge von Attributen beschrieben. Während die ID einen Cache-Inhalt eindeutig identifiziert, kann ein Attribut in der Beschreibung mehrerer Inhalte auftauchen. Sie werden am Beispiel des GP-Blogs lediglich die Identifikation von Cache-Inhalten mittels ID kennenlernen. Weitere gemeinsame Methoden aller Handler sind countDataItems(), um die Anzahl an Speicherinhalten zu ermitteln, die bestimmte Kriterien erfüllen, und getRemainingLifetime(), um die restliche Lebenszeit einer Speicherzelle zu ermitteln. Wie der Name der letzten Methode bereits andeutet, ermöglicht es ein Cache-Handler, gespeicherte Inhalte automatisch zeitgesteuert invalide werden zu lassen. So können Sie über die Optionen des Handlers, die Sie in Kürze kennenlernen, bestimmen, nach welcher Speicherzeit ein Inhalt ungültig wird und neu generiert werden muss. Die restore()-Methode gibt hier wie auch im Fall, dass kein passender Inhalt vorhanden ist, den Wert false zurück. #### Das Dateisystem als Cache Die mit der Cache-Komponente ausgelieferten Backend-Handler basieren alle auf dem Caching im Dateisystem, speichern also Daten auf der Festplatte. Alternative Möglichkeiten wie das Caching in einer Datenbank oder im Arbeitsspeicher sind angedacht, bisher allerdings noch nicht realisiert. Da alle Handler für das Caching auf Dateisystemebene einige Gemeinsamkeiten aufweisen, gibt es eine weitere abstrakte Klasse, die alle drei Backend-Handler erweitern. Auf diese Zwischenebene mit dem Namen ezcCacheStorageFile gehen wir an dieser Stelle nicht genauer ein, sondern stellen lediglich die drei implementierten Handler vor. Die drei Handler unterscheiden sich zum einen in der Art der Daten, die sie verarbeiten können, zum anderen in der Methode der Speicherung. ezcCacheStorageFilePlain-Instanzen sind in der Lage, skalare PHP-Datentypen zu cachen, indem die Daten als Text in einer Datei gespeichert werden. Dies ist wohl die bekannteste Form des Cachings. Nachteil dieses Handlers ist, dass lediglich einfache Daten wie Strings, Zahlen oder boolesche Werte gespeichert werden können; komplexe Datenstrukturen lassen sich so schwierig speichern. Dieses Manko beheben die beiden anderen Backend-Handler ezcCacheStorageFileArray und ezcCacheStorageFileEvalArray. Beide sind in der Lage, neben skalaren Datentypen auch Arrays zu verarbeiten, jedoch keine Objekte oder spezielle Datentypen.
Einschränkungen beim Caching
Die vermeintlich einfache Aktion des Cachings, also des Zwischenspeicherns von Daten, stellt sich komplizierter dar als gedacht. Zwar ist es noch recht einfach, skalare Daten zu cachen, denn diese können einfach in eine Datei geschrieben werden, spätestens bei einem Array ist dies aber nicht mehr so einfach möglich. Denn ein Array muss serialisiert werden.
Serialisieren bedeutet, dass die Struktur des Arrays zusammen mit dem Inhalt in einen String codiert werden muss. Wo dies noch hervorragend mit einfachen Arrays funktioniert, die lediglich skalare Daten oder weitere Arrays als Elemente beinhalten, ist dies bei Objekten und Referenzen sowie Spezialtypen wie Ressourcen nicht mehr möglich.
Diese Datentypen sind nur schwer zu lesen oder gar nicht serialisierbar. Letzteres gilt für alle Ressourcen. Es macht beispielsweise keinen Sinn, eine Datenbankverbindung zu cachen. Objekte werden von allen mitgelieferten Cache-Handlern bislang verweigert. Zwar ist es theoretisch möglich, Objekte in PHP zu serialisieren, Probleme treten aber spätestens bei rekursiven Referenzen auf, die in der objektorientierten Programmierung üblich sind.
Der Unterschied der beiden Array-Backend-Handler liegt in der Art, wie sie die ihnen übergebenen Daten speichern. Während Instanzen der Klasse ezcCacheStorageFileArray die serialize()-Funktion aus PHP verwenden, um das erhaltene Array zu serialisieren und es dann in eine Datei zu speichern (dementsprechend auf dem Rückweg deserialize()), geht ezcCacheStorageFileEvalArray einen anderen Weg. Dieser Handler speichert die Ausgabe der PHP-Funktion var_export() in einer Datei und stellt die exportierten Daten durch Inkludieren der so entstandenen PHP-Sourcecodedatei wieder her. Dies ist im Normalfall nicht wesentlich schneller oder langsamer als der Weg über serialize(), allerdings können PHP-Dateien von einem Byte-Code-Cache auf einer weiteren Ebene gecachet werden, was die Wiederherstellung der Daten beschleunigen kann. Alle drei vorgestellten Cache-Handler bieten natürlich die Basismethoden an, über die alle Cache-Handler verfügen. Sie haben diese bereits im letzten Abschnitt kennengelernt. Lediglich die Methoden restore() zum Wiederherstellen von Daten und delete() zum Löschen können einen zusätzlichen Parameter namens $search verarbeiten, dessen Standardwert true ist. Im Dateisystem ist es möglich, mehrere Ebenen von Caches zu verschachteln, indem Slash-Zeichen (/) in der ID verwendet werden. Die so entstehenden Verzeichnisebenen durchsuchen die beiden Methoden automatisch, falls dies beim Aufruf nicht unterbunden und nicht auf Anhieb ein passender Inhalt gefunden wird. Die für dateibasierte Handler zuständige Optionen-Klasse ezcCacheStorageFileOptions unterstützt neben $ttl, der Time-To-Live-Option, noch die Optionen $extension und $permissions. Die Time-To-Live-Option bestimmt die Lebenszeit eines Cache-Items, also diejenige Zeit in Sekunden, nach der ein Speicherinhalt automatisch invalide wird. Mit $extension wird die Dateiendung für Cache-Dateien festgelegt. Und $permissions enthält einen Integer-Wert, der in oktaler Schreibweise gelesen dem Unix-Dateiberechtigungswert [http://kris.koehntopp.de/artikel/unix/zugriffsrechte/ ] neu erstellter Cache-Dateien entspricht. Der Wert 0777 – die 0 stammt von der Darstellung im 8er-System – bedeutet beispielsweise, dass allen Benutzern das Lesen, Schreiben und Ausführen der Dateien gestattet ist. #### Der Cache-Manager Die Klasse ezcCacheManager stellt Mechanismen bereit, um Instanzen der Backend-Handler zu verwalten. Dabei verwirklicht die Manager-Klasse eine Art eigenes Lazy-Initialization, wie Sie es bereits von anderen Komponenten wie beispielsweise Database kennen. Allerdings geht die Cache-Komponente hier einen anderen Weg als der Standard in eZ Components, da sie diesen Lazy-Initialization-Mechanismus schon bereitstellte, bevor das generelle Konzept von Lazy-Initialization in eZ Components Eingang gefunden hatte. Der Cache-Manager erlaubt Ihnen, mit Hilfe der Methode createCache() neue Handler-Instanzen zu erzeugen, die anschließend unter einem vom Manager vergebenen Namen abrufbar sind. Allerdings erzeugt der Manager den entsprechenden Handler nicht direkt beim Aufruf von createCache(), sondern speichert lediglich die übergebenen Konfigurationsinformationen. Er erzeugt den Cache erst bei der ersten Verwendung, also einer Anfrage mittels getCache(). Sie können also alle benötigten Caches zentral für Ihre Anwendung im ezcCacheManager konfigurieren und an jeder Stelle darauf zugreifen. ### 17.2.3 Praktisches Als Nächstes werden Sie sehen, wie die Cache-Komponente praktisch im GP-Blog eingesetzt wird. Die bereits in Abschnitt 17.1, »Feed«, entwickelte Methode generateFeed() kommt nun in einer neuen Aktionsklasse namens gpBlogActionFeed zum Einsatz. Diese Klasse besitzt zwei Methoden zur Bearbeitung von Slots, dem Benachrichtigungsmechanismus, den Sie bereits aus Kapitel 3, »Die Applikationsbasis«, kennen: showFeed() und purgeFeed(). Während die erste Methode auf ein neues Signal namens feed hört und der Ausgabe des Feeds dient, ist die zweite dafür zuständig, den Cache des Feeds zu löschen, sobald ein neuer Eintrag geschrieben wird. Für diese Information des erfolgreichen Speicherns eines Eintrags existiert bereits ein eigenes Signal namens save_entry_success. Beide Methoden haben mit dem Caching des in Abschnitt 17.1, »Feed«, erstellten RSS-Feeds zu tun, das über einen Plain-File-Backend-Handler erfolgt. #### Einen Cache konfigurieren Zunächst muss also der zu verwendende Cache im Cache-Manager konfiguriert werden. Da beide Aktionsmethoden den Backend-Handler benötigen, wird er innerhalb der statischen registerSlots()-Methode instanziiert. Diese Methode wird bei jedem Request an das GP-Blog aufgerufen, um die von der Aktions-Klasse bereitgestellten Slots zu ermitteln. So wird der benötigte Cache auch dann konfiguriert, wenn er nicht verwendet wird. Wie Sie im letzten Abschnitt aber gesehen haben, ist der dabei entstehende Overhead vernachlässigbar.
    ezcCacheManager::createCache(
        'feed',
        dirname( __FILE__ ) . '/../../cache/feed/',
        'ezcCacheStorageFilePlain',
        array(
            'ttl' => 1800,
        )
    );
Listing 17.4 Das Cache-Objekt konfigurieren Der hier im Cache-Manager erzeugte Cache hat die ID feed, welche später verwendet wird, um auf den Cache zuzugreifen. Das Verzeichnis cache/feed/ unterhalb von stage15/, in dem Cache-Inhalte abgelegt werden, muss vorher angelegt werden. Es müssen hierfür Schreibrechte für den Webserver vorhanden sein, damit Cache-Dateien entsprechend angelegt werden können. Die angegebene Backend-Klasse speichert die Cache-Inhalte in serialisierter Form auf der Festplatte. Dies ist ideal für den XML-Text des erzeugten Feeds. Die Time-To-Live-Einstellung von 1800 Sekunden bedeutet eine Lebenszeit von 30 Minuten für die gecacheten Inhalte. Eigentlich wird diese Einstellung hier nicht benötigt, da der Cache manuell gelöscht wird. Sie könnten also alternativ für $ttl den Wert false angeben, wodurch Cache-Inhalte nicht automatisch invalide werden. #### Inhalte cachen Der Cache-Manager kennt nun den benötigten Backend-Handler und stellt diesen auf Anfrage zur Verfügung. Der erste Verwendungsort liegt in der Methode showFeed(), die das entsprechende Signal verarbeitet und durch die URL http://gpblog/feed den RSS-Feed mit aktuellen Einträgen versorgen soll.
    public static function showFeed( ezcUrl $url, ezcUrlConfiguration
    $config )
    {
        $cache = ezcCacheManager::getCache( 'feed' );
        if ( ( $feed = $cache->restore( 'blog' ) ) === false )
        {
            $feed = self::generateFeed();
            $cache->store( 'blog', $feed );
        }

        header( 'Content-Type: text/xml' );
        echo $feed;
    }
Listing 17.5 Daten cachen Die Methode ruft zunächst das benötigte Cache-Objekt aus dem Cache-Manager ab. Da es vorher mit korrekten Einstellungen definiert wurde, erzeugt der Manager jetzt das Backend-Handler-Objekt und gibt es zurück. Danach erfolgt die Abfrage, ob gespeicherte Daten unter der Cache-ID 'blog' vorliegen. Ist dies nicht der Fall, so gibt die Methode restore() auf dem Cache-Objekt den Wert false zurück. Daraufhin wird die Neugenerierung der Feed-Daten angestoßen, die Sie bereits in Abschnitt 17.1, »Feed«, kennengelernt haben. Die so generierten XML-Daten werden mittels store() unter der entsprechenden ID im Cache abgelegt. Ob aus dem Cache geladen oder frisch generiert – nach Ablauf der Alternative liegen die auszugebenden Daten in der Variablen $feed vor. Die Methode verwendet hier nicht den aus Kapitel 3, »Die Applikationsbasis«, bekannten Signalmechanismus zur Ausgabe von Daten, da dieser den Inhaltstyp HTML an den Webbrowser liefert, es sich an dieser Stelle aber um RSS handelt. Speichern und Wiederherstellen von Cache-Inhalten bereiten also keine großen Schwierigkeiten. Gleiches gilt für das Löschen von Cache-Inhalten. #### Cache-Inhalte löschen Die Aktionsmethode purgeFeed() wird aufgerufen, sobald ein neuer Eintrag verfasst wurde. In diesem Fall ist die Feed-Darstellung nicht mehr aktuell, weshalb der Cache-Inhalt gelöscht wird. Beim nächsten Abruf der Feed-Daten erkennt der Backend-Handler, dass keine validen Daten vorliegen. Der Feed wird daraufhin neu generiert und gespeichert. Beim nächsten Aufruf sind dann also wieder valide Daten im Cache enthalten.
    public static function purgeFeed( ezcUrl $url,ð
        ezcUrlConfiguration $config )
    {
        $cache = ezcCacheManager::getCache( 'feed' );
        $cache->delete( 'blog' );
    }
Listing 17.6 Cache-Daten löschen Erneut wird die Instanz des Cache-Backends von der Manager-Klasse abgefragt. Die ID des zu löschenden Cache-Inhalts ist bekannt, da im GP-Blog nur ein einziger Inhalt im Cache gespeichert wird. Mit dieser ID wird nun die Methode delete() auf dem Cache-Objekt aufgerufen, die zunächst testet, ob ein Inhalt mit der entsprechenden ID vorliegt und diesen gegebenenfalls löscht. Findet der Handler keine passenden Daten, wird der Aufruf ignoriert. ### Ihr Kommentar Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück | <top> | vor >>
Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen? Ihre Meinung
Buchempfehlungen
| PHP 5.3 und MySQL 5.1
| Besser PHP programmieren
| Webshops mit Magento
| Sichere Webanwendungen
| PHP 5.3 und MySQL 5.1 - Videotraining
| Apache 2
| Suchmaschinen- Optimierung für Webentwickler
| Joomla! 1.5
Shopping
Versandkostenfrei bestellen in Deutschland und Österreich Info

Copyright © Galileo Press 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

[Galileo Computing]
Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de