ファイルやクラスの動的な読み込み

Zend_Loader クラスは、ファイルを動的に読み込むためのメソッドを提供します。

Zend_Loader 対 require_once()

Zend_Loader のメソッドは、読み込みたいファイルの名前が変化する場合に便利です。 たとえば、ユーザの入力やメソッドの引数などのパラメータに基づいたファイル名を使用する場合などです。 もし読み込むファイルやクラスの名前が決まっている場合は、 require_once() のような PHP の関数ではなくあえて Zend_Loader を使用するメリットはありません。

ファイルの読み込み

静的メソッド Zend_Loader::loadFile() は、PHP ファイルを読み込みます。 読み込まれるファイルには任意の PHP コードを含めることができます。 このメソッドは PHP 関数 include() のラッパーで、失敗した場合 (たとえば指定したファイルが存在しないなど) には FALSE を返します。

例510 loadFile() メソッドの例

Zend_Loader::loadFile($filename, $dirs=null, $once=false);

引数 $filename には読み込むファイル名を指定します。 ここにはパス情報を含めてはいけません。$filename に対してはセキュリティチェックが行われます。 $filename に含めることができるのは英数字、ダッシュ ("-")、 アンダースコア ("_") あるいはピリオド (".") だけです。 引数 $dirs にはそのような制限はありません。

引数 $dirs にはファイルを探すディレクトリを指定します。 NULL の場合は include_path の中のみを対象とします。 文字列あるいは配列を指定すると、指定されたディレクトリをまず探した後で、 それから include_path を探します。

引数 $once は論理値です。TRUE を指定すると、 Zend_Loader::loadFile()PHP の関数 include_once() でファイルを読み込みます。それ以外の場合は include() を使用します。

クラスの読み込み

静的メソッド Zend_Loader::loadClass($class, $dirs) は、PHP ファイルを読み込んでクラスが存在するかどうかを確かめます。

例511 loadClass() メソッドの例

Zend_Loader::loadClass('Container_Tree',
    array(
        '/home/production/mylib',
        '/home/production/myapp'
    )
);

クラスを指定する文字列は、アンダースコアを OS のパス区切り文字に変換して最後に '.php' を追加したものとなります。上の例では、Windows 上で 'Container_Tree' は 'Container\\Tree.php' となります。

$dirs に文字列あるいは配列を指定すると、 Zend_Loader::loadClass() は指定した順にそのディレクトリを探します。 そして最初に見つかったファイルを読み込みます。 ディレクトリ $dirs にファイルがみつからない場合は、 PHPinclude_path で指定された場所を探します。

ファイルが見つからない場合、あるいは読み込んだファイルにクラスが存在しない場合は Zend_Loader::loadClass()Zend_Exception をスローします。

ファイルの読み込みには Zend_Loader::loadFile() を使用するので、 クラス名として指定できるのは 英数字とハイフン ('-')、アンダースコア ('_') そしてピリオド ('.') だけです。

Loading Classes from PHP Namespaces

Starting in version 1.10.0, Zend Framework now allows loading classes from PHP namespaces. This support follows the same guidelines and implementation as that found in the PHP Framework Interop Group PSR-0 reference implementation.

Under this guideline, the following rules apply:

  • Each namespace separator is converted to a DIRECTORY_SEPARATOR when loading from the file system.

  • Each "_" character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR. The "_" character has no special meaning in the namespace.

  • The fully-qualified namespace and class is suffixed with ".php" when loading from the file system.

As examples:

  • \Doctrine\Common\IsolatedClassLoader => /path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php

  • \namespace\package\Class_Name => /path/to/project/lib/vendor/namespace/package/Class/Name.php

  • \namespace\package_name\Class_Name => /path/to/project/lib/vendor/namespace/package_name/Class/Name.php

ファイルが読み込み可能かどうかの確認

静的メソッド Zend_Loader::isReadable($pathname) は、指定した場所にファイルが存在して読み込み可能な場合に TRUE、それ以外の場合に FALSE を返します。

例512 isReadable() メソッドの例

if (Zend_Loader::isReadable($filename)) {
    // $filename で何かをします
}

引数 $filename で、調べたいファイル名を指定します。 ここにはパス情報を含めることもできます。 このメソッドは、PHP の関数 is_readable() のラッパーです。この関数は include_path を探しませんが、Zend_Loader::isReadable()include_path も検索対象に含めます。

Autoloader の使用法

Zend_Loader クラスには、PHP の SPL 自動ローダーに登録するためのメソッドが含まれています。そのコールバックメソッドが Zend_Loader::autoload() です。利便性を考慮して、 Zend_Loader では registerAutoload() 関数を提供しています。 この関数は、autoload() メソッドを登録するものです。 spl_autoload 拡張モジュールが使用できない環境の場合は、 registerAutoload() メソッドは Zend_Exception をスローします。

例513 自動ローダー用コールバックメソッドの登録例

Zend_Loader::registerAutoload();

Zend Framework の autoload コールバックを登録すると、 明示的に読み込まなくても Zend Framework のクラスを参照できるようになります。 autoload() メソッドは、クラスを参照する際に自動的に Zend_Loader::loadClass() を使用します。

Zend_Loader クラスを継承した場合は、registerAutoload() に引数を追加できます。この引数で、どのクラスから autoload() メソッドを登録するのかを指定します。

例514 autoload コールバックメソッドを継承クラスから登録する例

PHP における静的関数の参照の方法上、 loadClass()autoload() の両方のコードを実装する必要があります。 そして、autoload() では self::loadClass() をコールしなければなりません。 作成する autoload() メソッドが親クラスに self::loadClass() の処理を任せるのなら、 サブクラスのメソッドではなく親クラス側の同名のメソッドをコールします。

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');

autoload コールバックを削除することもできます。 registerAutoload() にはオプションで 2 番目の引数を指定することができ、 デフォルトでは TRUE が設定されるようになっています。 この引数を FALSE とすると、 指定したコールバックが SPL の autoload スタックから削除されます。