<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="zend.cache.theory">
    <title>Die Theorie des Cachens</title>

    <para>
        Es gibt 3 Schlüsselkonzepte in <classname>Zend_Cache</classname>. Eines ist die eindeutige
        Identifizierung (ein String), die benutzt wird, um Cache Datensätze zu identifizieren. Das
        zweite ist die <emphasis>'lifetime'</emphasis> Direktive, wie im Beispiel gezeigt; sie
        definiert, wie lange eine gecachte Ressource als 'frisch' betrachtet wird. Das dritte
        Konzept ist die bedingte Ausführung, so das Teile des Codes komplett übersprungen werden
        können, was die Leistung steigert. Die Haupt-Frontend Funktion (eg.
        <methodname>Zend_Cache_Core::get()</methodname>) ist immer so gestaltet, das
        <constant>FALSE</constant> zurückgegeben wird, wenn ein Cache fehlt. Aber nur, wenn das für
        die Natur des Frontends Sinn macht. Das erlaubt es Endbenutzern, die Teile des Codes, die
        gecached (oder übersprungen) werden sollen, in
        <emphasis><methodname>if()</methodname>{ ... }</emphasis> Anweisungen zu umhüllen, wobei
        die Bedingung die <classname>Zend_Cache</classname> Methode selbst ist. Am Ende der Blöcke
        muss das erstellte auf alle Fälle gespeichert werden (z.B.
        <methodname>Zend_Cache_Core::save()</methodname>).
    </para>

    <note>
        <para>
            Das Design der bedingten Ausführung des erzeugten Codes ist in einigen Frontends nicht
            notwendig (<emphasis>Function</emphasis>, zum Beispiel) wenn die komplette Logik im
            verwendeten Frontend integriert ist.
        </para>
    </note>

    <note>
        <para>
            'Cache hit' ist ein Ausdruck für eine Bedingung, wenn ein Cache Datensatz gefunden
            wurde, er gültig und 'frisch' ist (in anderen Worten, er ist noch nicht abgelaufen).
            'Cache miss' ist alles andere. Wenn ein 'Cache miss' passiert, müssen die Daten erzeugt
            werden (wie man es normalerweise tun würde) und anschließend cachen. Wenn ein
            'Cache hit' geschieht muß, auf der anderen Seite, das Backend automatisch den Datensatz
            vom Cache transparent holen.
        </para>
    </note>

    <sect2 id="zend.cache.factory">
        <title>Die Zend_Cache Factory Methode</title>

        <para>
            Ein guter Weg, um eine verwendbare Instanz eines <classname>Zend_Cache</classname>
            Frontends zu erstellen, wird im folgenden Beispiel gegeben:
        </para>

        <programlisting language="php"><![CDATA[
// Wir wählen ein Backend (zum Beispiel 'File' oder 'Sqlite'...)
$backendName = '[...]';

// Wir wählen ein Frontend (zum Beispiel 'Core', 'Output', 'Page'...)
$frontendName = '[...]';

// Wir definieren ein Array von Optionen für das gewählte Frontend
$frontendOptions = array([...]);

// Wir definieren ein Array von Optionen für das gewählte Backend
$backendOptions = array([...]);

// Wir erstellen eine gute Instanz
// (natürlich sind die letzten 2 Argumente optional)
$cache = Zend_Cache::factory($frontendName,
                             $backendName,
                             $frontendOptions,
                             $backendOptions);
]]></programlisting>

        <para>
            In den folgenden Beispielen wird angenommen, dass die <varname>$cache</varname> Variable
            ein gültiges, initiiertes Frontend wie gezeigt enthält und dass verstanden wird, wie
            Parameter an das ausgewählte Backend übergeben werden.
        </para>

        <note>
            <para>
                Immer <methodname>Zend_Cache::factory()</methodname> benutzen, um eine Frontend
                Instanz zu bekommen. Das selbstständige Instantiieren von Frontends und Backends
                funktioniert nicht so wie erwartet.
            </para>
        </note>
    </sect2>

    <sect2 id="zend.cache.tags">
        <title>Markierte Datensätze</title>

        <para>
            Markierungen sind ein Weg um Cache Datensätze zu kategorisieren. Wenn der Cache mit der
            <methodname>save()</methodname> Methode abgespeichert werden soll, kann ein Array mit
            Markierungen für diesen Datensatz angelegt werden. Dann besteht die Möglichkeit, alle
            markierten Cache Datensätze mit einer bestimmten Markierung (oder Markierungen), zu
            löschen:
        </para>

        <programlisting language="php"><![CDATA[
$cache->save($huge_data, 'myUniqueID', array('tagA', 'tagB', 'tagC'));
]]></programlisting>

        <note>
            <para>
                Man beachte, dass die <methodname>save()</methodname> Method einen optionales,
                viertes Argument akzeptiert: <varname>$specificLifetime</varname> (wenn !=
                <constant>FALSE</constant>, setzt es eine spezifische Laufzeit für diesen speziellen
                Cache Eintrag)
            </para>
        </note>
    </sect2>

    <sect2 id="zend.cache.clean">
        <title>Löschen des Caches</title>

        <para>
            Um eine bestimmte Cache ID zu entfernen oder annullieren, kann die
            <methodname>remove()</methodname> Methode benutzt werden:
        </para>

        <programlisting language="php"><![CDATA[
$cache->remove('idToRemove');
]]></programlisting>

        <para>
            Um mehrere Cache IDs mit einer Operation zu entfernen oder annulieren, kann die
            <methodname>clean()</methodname> Methode benutzt werden. Zum Beispiel um alle Cache
            Datensätze zu entfernen :
        </para>

        <programlisting language="php"><![CDATA[
// Löschen aller Datensätze
$cache->clean(Zend_Cache::CLEANING_MODE_ALL);

// Nur abgelaufene löschen
$cache->clean(Zend_Cache::CLEANING_MODE_OLD);
]]></programlisting>

        <para>
            Um Cache Einträge zu löschen, die zu den Tags 'tagA' und 'tagC' entsprechen :
        </para>

        <programlisting language="php"><![CDATA[
$cache->clean(
    Zend_Cache::CLEANING_MODE_MATCHING_TAG,
    array('tagA', 'tagC')
);
]]></programlisting>

        <para>
            Um Cache Einträge zu löschen die den Tags 'tagA' oder 'tagC' nicht entsprechen:
        </para>

        <programlisting language="php"><![CDATA[
$cache->clean(
    Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG,
    array('tagA', 'tagC')
);
]]></programlisting>

        <para>
            Um Cache Einträge zu löschen, die zu den Tags 'tagA' oder 'tagC' entsprechen :
        </para>

        <programlisting language="php"><![CDATA[
$cache->clean(
    Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG,
    array('tagA', 'tagC')
);
]]></programlisting>

        <para>
            Mögliche Löschmodi sind: <constant>CLEANING_MODE_ALL</constant>,
            <constant>CLEANING_MODE_OLD</constant>,
            <constant>CLEANING_MODE_MATCHING_TAG</constant>,
            <constant>CLEANING_MODE_NOT_MATCHING_TAG</constant> und
            <constant>CLEANING_MODE_MATCHING_ANY_TAG</constant>. Die letzteren sind, wie deren
            Namen vermuten lassen, kombiniert mit einem Array von Markierungen für die
            Löschoperation.
        </para>
    </sect2>
</sect1>
