<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.loader.load">

    <title>Динамическая загрузка файлов и классов</title>

    <para>
        Класс <classname>Zend_Loader</classname> включает в себя методы,
        помогающие производить динамическую загрузку файлов.
    </para>

    <tip>
        <title>Zend_Loader vs. require_once()</title>
        <para>
            Методы <classname>Zend_Loader</classname> лучше всего использовать,
            когда имя файла для загрузки является переменным - например,
            если оно базируется на данных, введенных пользователем,
            или аргументе метода.
            Если вы загружаете файл или класс, чье имя является постоянным,
            то использование <classname>Zend_Loader</classname>
            не дает каких-либо преимуществ по сравнению использованием обычных
            функций PHP, таких, как
            <ulink url="http://php.net/require_once"><code>require_once()</code></ulink>.
        </para>
    </tip>

    <sect2 id="zend.loader.load.file">

        <title>Загрузка файлов</title>

        <para>
            Статический метод <code>Zend_Loader::loadFile()</code> загружает
            файл PHP. Загружаемый файл должен содержать код PHP. Метод является
            оберткой к PHP-функции
            <ulink url="http://php.net/include"><code>include()</code></ulink>.
            Этот метод возвращает <constant>FALSE</constant> в случае
            неуспеха - например, если требуемый файл не существует.
        </para>

        <example id="zend.loader.load.file.example">
            <title>Пример использования метода loadFile()</title>
            <programlisting language="php"><![CDATA[
Zend_Loader::loadFile($filename, $dirs=null, $once=false);
]]></programlisting>
    </example>

        <para>
            Аргумент <varname>$filename</varname> задает имя файла для загрузки, он
            не должен содержать путь к файлу. В целях безопасности производится
            проверка <varname>$filename</varname>. <varname>$filename</varname> должен
            содержать только алфавитно-цифровые символы, тире ("-"), знак
            подчеркивания ("_") и точку ("."). На аргумент <varname>$dirs</varname>
            эти ограничения не распространяются.
        </para>

        <para>
            Аргумент <varname>$dirs</varname> задает директории, в которых должен
            производиться поиск файла. Если его значение равно
            <constant>NULL</constant>, то для поиска используется только
            <code>include_path</code>. Если его значение является строкой или
            массивом, то файл сначала ищется в данной директории (директориях),
            а затем в <code>include_path</code>.
        </para>

        <para>
            Аргумент <varname>$once</varname> является значением булевого типа. Если
            равен <constant>TRUE</constant>, то <code>Zend_Loader::loadFile()</code> для
            загрузки файла использует PHP-функцию
            <ulink url="http://php.net/include"><code>include_once()</code></ulink>,
            иначе используется функция <ulink url="http://php.net/include_once"><code>include()</code></ulink>.
        </para>

    </sect2>

    <sect2 id="zend.loader.load.class">

        <title>Загрузка классов</title>

        <para>
            Статический метод <code>Zend_Loader::loadClass($class, $dirs)</code>
            загружает файл PHP и затем проверяет наличие требуемого класса.
        </para>

        <example id="zend.loader.load.class.example">
            <title>Пример использования метода loadClass()</title>
            <programlisting language="php"><![CDATA[
Zend_Loader::loadClass('Container_Tree',
    array(
        '/home/production/mylib',
        '/home/production/myapp'
    )
);
]]></programlisting>
        </example>

        <para>
            Строка, задающая класс, преобразуется в относительный путь
            посредством замены знаков подчеркивания разделителями директорий,
            используемыми в вашей ОС, и добавления расширения '.php'. В примере
            выше на Windows будет использоваться путь 'Container\\Tree.php'.
        </para>

        <para>
            Если <varname>$dirs</varname> является строкой или массивом, то
            <code>Zend_Loader::loadClass()</code> ищет в директориях в
            том порядке, в котором они были определены. Загружается первый
            найденный файл. Если файл не найден в директориях
            <varname>$dirs</varname>, то производится поиск в <code>include_path</code>.
        </para>

        <para>
            Если файл не найден, или класс не существует после загрузки, то
            <code>Zend_Loader::loadClass()</code> бросает
            исключение <code>Zend_Exception</code>.
        </para>

        <para>
            Для загрузки используется метод
            <code>Zend_Loader::loadFile()</code>, поэтому имя класса должно
            содержать только алфавитно-цпфровые символы, тире ('-'), знак
            подчеркивания ('_') и точку ('.').
        </para>

    </sect2>

    <sect2 id="zend.loader.load.isreadable">

        <title>Проверка на возможность чтения из файла</title>

        <para>
            Статический метод <code>Zend_Loader::isReadable($pathname)</code>
            возвращает <constant>TRUE</constant>, если по заданному пути существует файл
            и он доступен для чтения, иначе возвращается <constant>FALSE</constant>.
        </para>

        <example id="zend.loader.load.isreadable.example">
            <title>Пример использования метода isReadable()</title>
            <programlisting language="php"><![CDATA[
if (Zend_Loader::isReadable($filename)) {
    // делаем что-либо с файлом $filename
}
]]></programlisting>
        </example>

        <para>
            Аргумент <varname>$filename</varname> задает имя файла для проверки. Он
            может содержать путь к файлу. Этот метод является оберкой к
            PHP-функции
            <ulink url="http://php.net/is_readable"><code>is_readable()</code></ulink>.
            Метод <code>Zend_Loader::isReadable()</code> производит поиск в
            <code>include_path</code>, в то время как <code>is_readable()</code>
            этого не делает.
        </para>

    </sect2>

    <sect2 id="zend.loader.load.autoload">

        <title>Использование автозагрузчика</title>

        <para>
            Класс <classname>Zend_Loader</classname> содержит метод, который
            можно регистрировать
            через автозагрузчик PHP SPL. <code>Zend_Loader::autoload()</code>
            является методом обратного вызова. Для удобства
            <classname>Zend_Loader</classname> предоставляет метод
            <code>registerAutoload()</code> для регистрации
            его метода <code>autoload()</code>. Если в используемой среде
            PHP отсутствует расширение <code>spl_autoload</code>, то метод
            <code>registerAutoload()</code> бросает исключение
            <classname>Zend_Exception</classname>.
        </para>

        <example id="zend.loader.load.autoload.example">
            <title>Пример регистрации метода автозагрузки</title>
            <programlisting language="php"><![CDATA[
Zend_Loader::registerAutoload();
]]></programlisting>
        </example>

        <para>
            После регистрации метода автозагрузки вы можете
            ссылаться на классы из Zend Framework без их явной загрузки.
            Метод <code>autoload()</code> автоматически запускает метод
            <code>Zend_Loader::loadClass()</code>, когда вы ссылаетесь на класс.
        </para>

        <para>
            Если вы расширили класс <classname>Zend_Loader</classname>, то
            можете передавать методу <code>registerAutoload()</code>
            опциональный аргумент для указания
            класса, из которого следует регистрировать метод
            <code>autoload()</code>.
        </para>

        <example id="zend.loader.load.autoload.example-extended">
            <title>Пример регистрации метода автозагрузки из расширенного класса</title>
            <para>
                В силу особенностей семантики статических функций в PHP
                вы должны реализовать код для обоих методов
                <code>loadClass()</code> и <code>autoload()</code>, при этом
                <code>autoload()</code> должен вызывать
                <code>self::loadClass()</code>. Если ваш метод
                <code>autoload()</code> делегирует родительскому классу вызов
                <code>self::loadClass()</code> то будет вызван метод
                родительского класса, не подкласса.
            </para>
            <programlisting language="php"><![CDATA[
class My_Loader extends Zend_Loader
{
    public static function loadClass($class, $dirs = null)
    {
        parent::loadClass($class, $dirs);
    }

    public static function autoload($class)
    {
        try {
            self::loadClass($class);
            return $class;
        } catch (Exception $e) {
            return false;
        }
    }
}

Zend_Loader::registerAutoload('My_Loader');
]]></programlisting>
        </example>

        <para>
            Регистрацию метода автозагрузки можно отменить.
            Метод <code>registerAutoload()</code> имеет опциональный
            второй аргумент, его значением по умолчанию является
            <constant>TRUE</constant>. Если этот аргумент равен <constant>FALSE</constant>,
            то данный метод автозагрузки удаляется из стека SPL.
        </para>

    </sect2>

</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
