<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.loader.autoloader">
    <title>The Autoloader</title>

    <para>
        <classname>Zend_Loader_Autoloader</classname> introduces a comprehensive
        autoloading solution for Zend Framework. It has been designed with
        several goals in mind:
    </para>

    <itemizedlist>
        <listitem><para>
            Provide a true namespace autoloader. (Previous incarnations
            intercepted all userland namespaces.)
        </para></listitem>

        <listitem><para>
            Allow registering arbitrary callbacks as autoloaders, and manage
            them as a stack. (At the time of this writing, this overcomes some
            issues with <code>spl_autoload</code>, which does not allow
            re-registering a callback that utilizes an instance method.)
        </para></listitem>

        <listitem><para>
            Allow optimistic matching of namespaces to provide faster class
            resolution.
        </para></listitem>
    </itemizedlist>

    <para>
        <classname>Zend_Loader_Autoloader</classname> implements a singleton, making it
        unversally accessible. This provides the ability to register additional
        autoloaders from anywhere in your code as necessary.
    </para>

    <sect2 id="zend.loader.autoloader.usage">
        <title>Using the Autoloader</title>

        <para>
            The first time an instance of the autoloader is retrieved, it
            registers itself with <code>spl_autoload</code>. You retrieve an
            instance using the <methodname>getInstance()</methodname> method:
        </para>

        <programlisting language="php"><![CDATA[
$autoloader = Zend_Loader_Autoloader::getInstance();
]]></programlisting>

        <para>
            By default, the autoloader is configured to match the "Zend_" and
            "ZendX_" namespaces. If you have your own library code that uses
            your own namespace, you may register it with the autoloader using
            the <methodname>registerNamespace()</methodname> method. For instance, if your
            library code is prefixed with "My_", you could do so as follows:
        </para>

        <programlisting language="php"><![CDATA[
$autoloader->registerNamespace('My_');
]]></programlisting>

        <note>
            <title>Namespace Prefixes</title>

            <para>
                You'll note that the previous example uses "My_" and not "My".
                This is because <classname>Zend_Loader_Autoloader</classname> is intended
                as a general purpose autoloader, and does not make the
                assumption that a given class prefix namespace includes an
                underscore. If your class namespace <emphasis>does</emphasis>
                include one, you should include it when registering your
                namespace.
            </para>
        </note>

        <para>
            You can also register arbitrary autoloader callbacks, optionally
            with a specific namespace (or group of namespaces).
            <classname>Zend_Loader_Autoloader</classname> will attempt to match these
            first before using its internal autoloading mechanism.
        </para>

        <para>
            As an example, you may want to utilize one or more eZcomponents
            components with your Zend Framework application. To use its
            autoloading capabilities, push it onto the autoloader stack using
            <methodname>pushAutoloader()</methodname>:
        </para>

        <programlisting language="php"><![CDATA[
$autoloader->pushAutoloader(array('ezcBase', 'autoload'), 'ezc');
]]></programlisting>

        <para>
            This tells the autoloader to use the eZcomponents autoloader for
            classes beginning with "ezc".
        </para>

        <para>
            You can use the <methodname>unshiftAutoloader()</methodname> method to add the
            autoloader to the beginning of the autoloader chain.
        </para>

        <para>
            By default, <classname>Zend_Loader_Autoloader</classname> does no error
            suppression when using its internal autoloader, which utilizes
            <methodname>Zend_Loader::loadClass()</methodname>. Most of the time, this is
            exactly what you want. However, there may be cases where you want to
            suppress them. You can do this using
            <methodname>suppressNotFoundWarnings()</methodname>:
        </para>

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

        <para>
            Finally, there may be times when you want the autoloader to load any
            namespace. For instance, PEAR libraries do not share a common
            namespace, making specifying individual namespaces difficult when
            many PEAR components are in use. You can use the
            <methodname>setFallbackAutoloader()</methodname> method to have the autoloader
            act as a catch-all:
        </para>

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

    <sect2 id="zend.loader.autoloader.interface">
        <title>The Autoloader Interface</title>

        <para>
            Besides being able to specify arbitrary callbacks as autoloaders,
            Zend Framework also defines an interface autoloading classes may
            imlement, <classname>Zend_Loader_Autoloader_Interface</classname>:
        </para>

        <programlisting language="php"><![CDATA[
interface Zend_Loader_Autoloader_Interface
{
    public function autoload($class);
}
]]></programlisting>

        <para>
            When using this interface, you can simply pass a class instance to
            <classname>Zend_Loader_Autoloader</classname>'s <methodname>pushAutoloader()</methodname>
            and <methodname>unshiftAutoloader()</methodname> methods:
        </para>

        <programlisting language="php"><![CDATA[
// Assume Foo_Autoloader implements Zend_Loader_Autoloader_Interface:
$foo = new Foo_Autoloader();

$autoloader->pushAutoloader($foo, 'Foo_');
]]></programlisting>
    </sect2>

    <sect2 id="zend.loader.autoloader.reference">
        <title>Autoloader Reference</title>

        <para>
            Below, please find a guide to the methods available in
            <classname>Zend_Loader_Autoloader</classname>.
        </para>

        <table id="zend.loader.autoloader.reference.api">
            <title>Zend_Loader_Autoloader Methods</title>
            <tgroup cols="4">
                <thead>
                    <row>
                        <entry>Method</entry>
                        <entry>Return Value</entry>
                        <entry>Parameters</entry>
                        <entry>Description</entry>
                    </row>
                </thead>
                <tbody>
                    <row>
                        <entry><methodname>getInstance()</methodname></entry>
                        <entry><classname>Zend_Loader_Autoloader</classname></entry>
                        <entry>N/A</entry>
                        <entry><para>
                            Retrieve the <classname>Zend_Loader_Autoloader</classname>
                            singleton instance. On first retrieval, it registers
                            itself with <code>spl_autoload</code>. This method
                            is static.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>resetInstance()</methodname></entry>
                        <entry><code>void</code></entry>
                        <entry>N/A</entry>
                        <entry><para>
                            Resets the state of the <classname>Zend_Loader_Autoloader</classname>
                            singleton instance to it's original state,
                            unregistering all autoloader callbacks and all
                            registered namespaces.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>autoload($class)</methodname></entry>
                        <entry><code>string|false</code></entry>
                        <entry><itemizedlist>
                            <listitem><para>
                                <varname>$class</varname>, <emphasis>required</emphasis>.
                                A string class name to load.
                            </para></listitem>
                        </itemizedlist></entry>
                        <entry><para>
                            Attempt to resolve a class name to a file and load
                            it.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>setDefaultAutoloader($callback)</methodname></entry>
                        <entry><classname>Zend_Loader_Autoloader</classname></entry>
                        <entry><itemizedlist>
                            <listitem><para>
                                <varname>$callback</varname>, <emphasis>required</emphasis>.
                            </para></listitem>
                        </itemizedlist></entry>
                        <entry><para>
                            Specify an alternate PHP callback to use for the
                            default autoloader implementation.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>getDefaultAutoloader()</methodname></entry>
                        <entry><code>callback</code></entry>
                        <entry>N/A</entry>
                        <entry><para>
                            Retrieve the default autoloader implementation; by
                            default, this is
                            <methodname>Zend_Loader::loadClass()</methodname>.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>setAutoloaders(array $autoloaders)</methodname></entry>
                        <entry><classname>Zend_Loader_Autoloader</classname></entry>
                        <entry><itemizedlist>
                            <listitem><para>
                                <varname>$autoloaders</varname>, <emphasis>required</emphasis>.
                            </para></listitem>
                        </itemizedlist></entry>
                        <entry><para>
                            Set a list of concrete autoloaders to use in the
                            autoloader stack. Each item in the autoloaders array
                            must be a PHP callback.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>getAutoloaders()</methodname></entry>
                        <entry><type>Array</type></entry>
                        <entry>N/A</entry>
                        <entry><para>
                            Retrieve the internal autoloader stack.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>getNamespaceAutoloaders($namespace)</methodname></entry>
                        <entry><type>Array</type></entry>
                        <entry><itemizedlist>
                            <listitem><para>
                                <varname>$namespace</varname>, <emphasis>required</emphasis>
                            </para></listitem>
                        </itemizedlist></entry>
                        <entry><para>
                            Fetch all autoloaders that have registered to load a
                            specific namespace.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>registerNamespace($namespace)</methodname></entry>
                        <entry><classname>Zend_Loader_Autoloader</classname></entry>
                        <entry><itemizedlist>
                            <listitem><para>
                                <varname>$namespace</varname>, <emphasis>required</emphasis>.
                            </para></listitem>
                        </itemizedlist></entry>
                        <entry><para>
                            Register one or more namespaces with the default
                            autoloader. If <varname>$namespace</varname> is a string,
                            it registers that namespace; if it's an array of
                            strings, registers each as a namespace.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>unregisterNamespace($namespace)</methodname></entry>
                        <entry><classname>Zend_Loader_Autoloader</classname></entry>
                        <entry><itemizedlist>
                            <listitem><para>
                                <varname>$namespace</varname>, <emphasis>required</emphasis>.
                            </para></listitem>
                        </itemizedlist></entry>
                        <entry><para>
                            Unregister one or more namespaces from the default
                            autoloader. If <varname>$namespace</varname> is a string,
                            it unregisters that namespace; if it's an array of
                            strings, unregisters each as a namespace.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>getRegisteredNamespace()</methodname></entry>
                        <entry><type>Array</type></entry>
                        <entry>N/A</entry>
                        <entry><para>
                            Returns an array of all namespaces registered with
                            the default autoloader.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>suppressNotFoundWarnings($flag = null)</methodname></entry>
                        <entry><code>boolean|Zend_Loader_Autoloader</code></entry>
                        <entry><itemizedlist>
                            <listitem><para>
                                <varname>$flag</varname>, <emphasis>optional</emphasis>.
                            </para></listitem>
                        </itemizedlist></entry>
                        <entry><para>
                            Set or retrieve the value of the flag used to
                            indicate whether the default autoloader
                            implementation should suppress "file not found"
                            warnings. If no arguments or a null value is passed,
                            returns a boolean indicating the status of the flag;
                            if a boolean is passed, the flag is set to that
                            value and the autoloader instance is returned (to
                            allow method chaining).
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>setFallbackAutoloader($flag)</methodname></entry>
                        <entry><classname>Zend_Loader_Autoloader</classname></entry>
                        <entry><itemizedlist>
                            <listitem><para>
                                <varname>$flag</varname>, <emphasis>required</emphasis>.
                            </para></listitem>
                        </itemizedlist></entry>
                        <entry><para>
                            Set the value of the flag used to indicate whether
                            or not the default autoloader should be used as a
                            fallback or catch-all autoloader for all namespaces.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>isFallbackAutoloader()</methodname></entry>
                        <entry><type>Boolean</type></entry>
                        <entry>N/A</entry>
                        <entry><para>
                            Retrieve the value of the flag used to indicate whether
                            or not the default autoloader should be used as a
                            fallback or catch-all autoloader for all namespaces.
                            By default, this is false.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>getClassAutoloaders($class)</methodname></entry>
                        <entry><type>Array</type></entry>
                        <entry><itemizedlist>
                            <listitem><para>
                                <varname>$class</varname>, <emphasis>required</emphasis>.
                            </para></listitem>
                        </itemizedlist></entry>
                        <entry><para>
                            Get the list of namespaced autoloaders that could
                            potentially match the provided class. If none match,
                            all global (non-namespaced) autoloaders are
                            returned.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>unshiftAutoloader($callback, $namespace = '')</methodname></entry>
                        <entry><classname>Zend_Loader_Autoloader</classname></entry>
                        <entry><itemizedlist>
                            <listitem><para>
                                <varname>$callback</varname>, <emphasis>required</emphasis>.
                                A valid PHP callback
                            </para></listitem>

                            <listitem><para>
                                <varname>$namespace</varname>, <emphasis>optional</emphasis>.
                                A string representing a class prefix namespace.
                            </para></listitem>
                        </itemizedlist></entry>
                        <entry><para>
                            Add a concrete autoloader implementation to the
                            beginning of the internal autoloader stack. If a
                            namespace is provided, that namespace will be used
                            to match optimistically; otherwise, the autoloader
                            will be considered a global autoloader.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>pushAutoloader($callback, $namespace = '')</methodname></entry>
                        <entry><classname>Zend_Loader_Autoloader</classname></entry>
                        <entry><itemizedlist>
                            <listitem><para>
                                <varname>$callback</varname>, <emphasis>required</emphasis>.
                                A valid PHP callback
                            </para></listitem>

                            <listitem><para>
                                <varname>$namespace</varname>, <emphasis>optional</emphasis>.
                                A string representing a class prefix namespace.
                            </para></listitem>
                        </itemizedlist></entry>
                        <entry><para>
                            Add a concrete autoloader implementation to the
                            end of the internal autoloader stack. If a
                            namespace is provided, that namespace will be used
                            to match optimistically; otherwise, the autoloader
                            will be considered a global autoloader.
                        </para></entry>
                    </row>

                    <row>
                        <entry><methodname>removeAutoloader($callback, $namespace = '')</methodname></entry>
                        <entry><classname>Zend_Loader_Autoloader</classname></entry>
                        <entry><itemizedlist>
                            <listitem><para>
                                <varname>$callback</varname>, <emphasis>required</emphasis>.
                                A valid PHP callback
                            </para></listitem>

                            <listitem><para>
                                <varname>$namespace</varname>, <emphasis>optional</emphasis>.
                                A string representing a class prefix namespace,
                                or an array of namespace strings.
                            </para></listitem>
                        </itemizedlist></entry>
                        <entry><para>
                            Remove a concrete autoloader implementation from
                            the internal autoloader stack. If a namespace or
                            namespaces are provided, the callback will be
                            removed from that namespace or namespaces only.
                        </para></entry>
                    </row>
                </tbody>
            </tgroup>
        </table>
    </sect2>
</sect1>
