Chapter 39. Zend_Loader

Table of Contents

39.1. 动态加载文件和类
39.1.1. 加载文件
39.1.2. 加载类
39.1.3. 判定某个文件是否可读
39.1.4. 使用 Autoloader
39.2. The Autoloader
39.2.1. Using the Autoloader
39.2.2. Selecting a Zend Framework version
39.2.3. The Autoloader Interface
39.2.4. Autoloader Reference
39.3. Resource Autoloaders
39.3.1. Resource autoloader usage
39.3.2. The Module Resource Autoloader
39.3.3. Using Resource Autoloaders as Object Factories
39.3.4. Resource Autoloader Reference
39.4. 加载插件
39.4.1. 基本用例
39.4.2. 处理插件路径
39.4.3. 测试插件和获取类的名字

39.1.  动态加载文件和类

Zend_Loader类可以帮助你动态加载文件。

[Tip] Zend_Loader vs. require_once()

Zend_Loader 最适合于加载的文件名是变量的情况(例如你要加载的文件的名称来自于用户的输入或者某个方法的参数)。如果你加载的文件名或类名是一个常量(即确定的文件,如/lib/test.php),则使用 Zend_Loader 并不比传统的PHP函数 require_once()有什么优势。

39.1.1.  加载文件

静态方法 Zend_Loader::loadFile() 加载PHP文件,被加载的文件可包含任何 PHP 代码。它其实是将PHP的include()函数封装而成的一个静态方法。当包含文件失败时,会抛出异常Zend_Exception,例如指定的文件不存在。

Example 39.1. loadFile() 方法范例

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

            

$filename参数指定需要加载的文件,注意$filename不需要指定任何路径,只需要文件名即可。ZF会对文件作安全性检查。$filename 只能由字母,数字,连接符-,下划线_及英文句号.组成(半角)。$dirs参数则不限,可以使用中文等。

$dirs 参数用来指定文件所在目录,可以是一个字符串或者数组。如果为 NULL,则程序将会到系统的 include_path 下寻找文件是否存在(include_path可在php.ini中设置--Haohappy注),如果是字符串或数组,则会到指定的目录下去找,然后才是 include_path

$once 参数为布尔类型,如果为 TRUEZend_Loader::loadFile() 使用 PHP 函数 include_once() 加载文件,否则就是 PHP 函数 include()。(本参数只能是true或false,两者区别就和include()和include_once()的区别一样。)

39.1.2.  加载类

静态方法Zend_Loader::loadClass($class, $dirs)用来加载一个 PHP 类文件,该文件名格式为“$className.php”(也就是说加载的文件名称必须和文件中的类同名)。loadClass()会检查文件中的类是否存在。

Example 39.2. Example of loadClass() method

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

            

类名将会根据下划线(作为目录分隔线)对应到相应目录下的PHP文件,并加上'.php',比如Container_Tree会指向Container\\Tree.php。

如果$dirs是一个字符串或数组, Zend_Loader::loadClass()会根据顺序查找相应目录,并加载第一个匹配的文件。如果文件不存在,则会查找 inculde_path 指定的目录。

如果文件不存在或者文件中相应的类不存在,那么 Zend_Loader::loadClass() 就会抛出一个 Zend_Exception 异常。

Zend_Loader::loadFile() 用来加载文件,所以类名中只能包含字母数字、连接符('-')、下划线('_')和句点('.')。

39.1.3.  判定某个文件是否可读

静态方法Zend_Loader::isReadable($pathname)判定某个文件是否存在并可读,可读则返回 TRUE ,否则返回 FALSE

Example 39.3. isReadable()示例:

if (Zend_Loader::isReadable($filename)) {
    // do something with $filename
}

            

$filename参数指定了要检查的文件名,包括路径信息。这个方法是将 PHP 函数is_readable()封装而成的,is_readable() 不会自动查找 include_path 下的文件,而 Zend::isReadable() 可以。

39.1.4.  使用 Autoloader

Zend_Loader 类包括一个可以用 PHP SPL autoloader 注册的方法。Zend_Loader::autoload() 是 callback 方法。为方便起见,Zend_Loader 提供 registerAutoload() 函数注册它的 autoload() 方法。如果 spl_autoload 扩展不在你的 PHP 环境中,那么 registerAutoload() 方法将抛出 Zend_Exception

Example 39.4.  注册 autoloader callback 方法范例

Zend_Loader::registerAutoload();

            

注册 Zend Framework autoload callback 后,可以不需要显式加载就可以从 Zend Framework 引用那些类。当应用一个类,autoload() 方法自动地使用 Zend_Loader::loadClass()

如果继承 Zend_Loader 类,可以给 registerAutoload() 一个可选的参数通过注册一个 autoload() 方法来指定类。

Example 39.5.  从继承类注册 autoload callback 方法范例

因为在 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 callback,registerAutoload() 有个可选的第二个参数,缺省为 true 。如果这个参数是 false, 那么 autoload callback 从 SPL autoload 栈里 unregistered 掉而不是注册。