<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="learning.autoloading.usage">
    <title>Grundsätzliche Verwendung von Autoloadern</title>

    <para>
        Jetzt da wir verstehen was Autoloading ist, und was die Ziele und das Design von Zend
        Framework's Autoloading Lösung sind, schauen wir und an wie
        <classname>Zend_Loader_Autoloader</classname> verwendet wird.
    </para>

    <para>
        Im einfachsten Fall wird die Klasse einfach mit "require" verwendet und anschließend
        instanziert. Da <classname>Zend_Loader_Autoloader</classname> ein Singleton ist (aus dem
        Grund da auch der <acronym>SPL</acronym> Autoloader eine einzelne Ressource ist) verwenden
        wir <methodname>getInstance()</methodname> um eine Instanz zu erhalten.
    </para>

    <programlisting language="php"><![CDATA[
require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();
]]></programlisting>

    <para>
        Standardmäßig erlaubt dies das Laden jeder Klasse mit dem Klassen Namespace Präfix "Zend_"
        oder "ZendX_", solange Sie im eigenen <property>include_path</property> liegen.
    </para>

    <para>
        Was passiert wenn man andere Namespace Präfix verwenden will? Der beste und einfachste Weg
        ist der Aufruf der <methodname>registerNamespace()</methodname> Methode auf der Instanz. Man
        kann einen einzelnen Namespace Präfix übergeben, oder ein Array von Ihnen:
    </para>

    <programlisting language="php"><![CDATA[
require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->registerNamespace('Foo_');
$loader->registerNamespace(array('Foo_', 'Bar_'));
]]></programlisting>

    <para>
        Alternativ kann man <classname>Zend_Loader_Autoloader</classname> sagen das es als
        "fallback" Autoloader arbeiten soll. Das bedeutet das er versuchen wird jede Klasse
        aufzulösen unabhängig vom Namespace Präfix.
    </para>

    <programlisting language="php"><![CDATA[
$loader->setFallbackAutoloader(true);
]]></programlisting>

    <warning>
        <title>Ein Fallback Autloader sollte nicht verwendet werden</title>

        <para>
            Wärend es nützlich erscheint <classname>Zend_Loader_Autoloader</classname> als Fallback
            Autoloader zu verwenden, empfehlen wir diese Praxis nicht.
        </para>

        <para>
            Intern verwendet <classname>Zend_Loader_Autoloader</classname>
            <methodname>Zend_Loader::loadClass()</methodname> um Klassen zu laden. Diese Methode
            verwendet <methodname>include()</methodname> um zu versuchen die gegebene Klassendatei
            zu laden. <methodname>include()</methodname> gibt ein boolsches
            <constant>FALSE</constant> zurück wenn es nicht erfolgreich war -- löst aber auch eine
            <acronym>PHP</acronym> Warnung aus. Der letztere Fakt kann zu einigen Problemen führen:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    Wenn <property>display_errors</property> aktiviert ist, ist die Warnung in der
                    Ausgabe enthalten.
                </para>
            </listitem>

            <listitem>
                <para>
                    Abhängig vom <property>error_reporting</property> Level den man ausgewählt hat,
                    könnte es auch die Logs zuschütten.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            Man kann die Fehlermeldungen unterdrücken (die Dokumentation von
            <classname>Zend_Loader_Autoloader</classname> gibt Details), aber man sollte beachten
            die Unterdrückung nur relevant ist wenn <property>display_errors</property> aktiviert
            ist; das Fehler Log wird die Meldung immer zeigen. Aus diesem Grund empfehlen wir die
            Namespace Präfixe welche der Autoloader behandeln soll, immer zu konfigurieren.
        </para>
    </warning>

    <note>
        <title>Namespace Präfixe vs PHP Namespaces</title>

        <para>
            Wärend dies geschrieben wurde, wurde <acronym>PHP</acronym> 5.3 herausgebracht. Mit
            dieser Version unterstützt <acronym>PHP</acronym> jetzt offiziell Namespaces.
        </para>

        <para>
            Trotzdem ist Zend Framework auf vor <acronym>PHP</acronym> 5.3 im Einsatz, und deshalb
            auch Namespaces. Wenn wir im Zend Framework auf "Namespaces" verweisen, verweisen wir
            auf eine Praxis bei der Klassen ein Hersteller "Namespace" vorangestellt wird. Als
            Beispiel wird allen Zend Framework Klassen "Zend_" vorangestellt -- das ist unser
            Hersteller "Namespace".
        </para>

        <para>
            Zend Framework plant die native Unterstützung von <acronym>PHP</acronym> Namespaces im
            Autoloader in zukünftigen Versionen, und seine eigene Bibliothek wird Namespaces
            beginnend mit Version 2.0.0 verwenden.
        </para>
    </note>

    <para>
        Wenn man eigene Autoloader hat, die man mit Zend Framework verwenden will -- möglicherweise
        einen Autoloader von einer anderen Bibliothek die man verwendet -- kann man das mit
        <classname>Zend_Loader_Autoloader</classname>'s <methodname>pushAutoloader()</methodname>
        und <methodname>unshiftAutoloader()</methodname> Methoden durchführen. Diese Methoden
        stellen Autoloader einer Kette voran welche aufgerufen wird, oder hängen Sie an, bevor Zend
        Framework's interner autoloading Mechanismus ausgeführt wird. Dieser Ansatz bietet die
        folgenden Vorteile:
    </para>

    <itemizedlist>
        <listitem>
            <para>
                Jede Methode nimmt ein zweites optionales Argument entgegen, einen Klassen Namespace
                Präfix. Dieser kann verwendet werden um anzuzeigen das der angegebene Autoloader nur
                verwendet werden soll wenn nach Klassen mit dem angegebenen Klassenpräfix gesehen
                wird. Wenn die aufgelöste Klasse diesen Präfix nicht hat, wird der Autoloader
                übergangen -- was zu Verbesserungen der Geschwindigkeit führen kann.
            </para>
        </listitem>

        <listitem>
            <para>
                Wenn man <methodname>spl_autoload()</methodname>'s Registry verändern muss, können
                alle Autoloader welche Callbacks sind und auf Methoden einer Instanz sind, Probleme
                verursachen da <methodname>spl_autoload_functions()</methodname> nicht exakt die
                gleichen Callbacks zurückgibt. <classname>Zend_Loader_Autoloader</classname> hat
                keine entsprechenden Begrenzungen.
            </para>
        </listitem>
    </itemizedlist>

    <para>
        Autoloader welche auf diesem Weg gemanaged werden können alle gültigen
        <acronym>PHP</acronym> Callbacks sein.
    </para>

    <programlisting language="php"><![CDATA[
// Die Funktion 'my_autoloader' dem Stack voranstellen,
// um Klassen mit dem Präfix 'My_' zu managen:
$loader->pushAutoloader('my_autoloader', 'My_');

// Die statische Methode Foo_Loader::autoload() dem Stack anhängen,
// um Klassen mit dem Präfix 'Foo_' zu managen:
$loader->unshiftAutoloader(array('Foo_Loader', 'autoload'), 'Foo_');
]]></programlisting>
</sect1>
