现在我们已经了解了,什么是自动加载器以及 Zend Framework 自动加载器解决方案的目标和设计,让我们看看如何使用 Zend_Loader_Autoloader。
在最简单的例子中,你简单的包括类,然后实例化它。由于 Zend_Loader_Autoloader 是一个单件模式(这是基于 SPL 自动加载器是一个单独资源的事实),我们使用 getInstance() 来检索一个实例。
require_once 'Zend/Loader/Autoloader.php'; Zend_Loader_Autoloader::getInstance();
默认的,这将允许加载任何类名前缀为 Zend_ 或者 ZendX_ 的类,只要它们(类名前缀为 Zend_ 或者 ZendX_ 的类)出现在你的 include_path 路径中。
如果你想使用其它的命名空间前缀?最好的办法,同时是最简单的,是调用实例中的 registerNamespace() 方法。你可以传递一个单独的命名空间前缀,或者一个数组:
require_once 'Zend/Loader/Autoloader.php'; $loader = Zend_Loader_AutoLoader::getInstance(); $loader->registerNamespace('Foo_'); $loader->registerNamespace(array('Foo_', 'Bar_'));
另外,你可以告诉 Zend_Loader_Autoloader 扮演一个 fallback 自动加载器。这意味着它将试图解析任何的类,而不管类名前缀是什么。
$loader->setFallbackAutoloader(true);
警告
不要使用一个 fallback 自动加载器。
当试图把 Zend_Loader_Autoloader 当作一个 fallback 自动加载器使用的时候,我们不赞成这样的实践。
在内部代码中,Zend_Loader_Autoloader 使用 Zend_Loader::loadClass() 来加载类。那种方法使用 include() 来试图加载指定的类文件。如果不成功,include() 将会返回 FALSE ——但是也会发出一条 PHP 警告。后面的行为将会导致一些问题:
- 如果 display_errors 被开启,警告将会被输出。
- 根据你所选择的 error_reporting 级别,它也会塞满你的日志。
你可以抑制错误信息(Zend_Loader_Autoloader 文档有关于这方面的详细描述),但是注意,抑制只对 display_errors 被开启有作用(即 display_errors 被开启的时候,你可以通过抑制错误信息从而不让错误信息输出),但是错误日志却总是显示相关信息。由于上述原因,我们建议总是要小心配置自动加载器的命名空间。
注意:命名空间前缀 VS PHP 命名空间
当写下本文档的时候,PHP 5.3 已经发行了。使用那个版本,PHP 现在有了对命名空间的官方支持。然而,Zend Framework 早于 PHP 5.3,命名空间也是如此。在 Zend Framework 内部,当我们说“命名空间”的时候,我们是指类被一个“命名空间”加为前缀这种实践。例如,所有的 Zend Framework 类的名字都以“Zend_”开关——这个就是我们的“命名空间”。Zend Framework 计划在将来的版本中提供内置的 PHP 命名空间支持,从2.0.0版本开始,它自己的库文件将使用命名空间。
如果你有一个定制的自动加载器想和 Zend Framework 的同时使用 ——可能是一个你使用的第三方库文件的自动加载器——你可以使用 Zend_Loader_Autoloader 中的 pushAutoloader() 和 unshiftAutoloader() 方法来管理它。这两种方法将分别把自动加载器附加和预加到一个链条上,这个链条将在 Zend Framework 内部自动加载机制之前优先被调用。这个办法提供以下好处:
自动加载器可以管理任何合法的 PHP callback。
// Append function 'my autoloader' to the stack, // to manage classes with the prefix 'My_': $loader->pushAutoloader('my_autoloader', 'My_'); // Prepend static method Foo_Loader::autoload() to the stack, // to manage classes with the prefix 'Foo ': $loader->unshiftAutoloader(array('Foo_Loader', 'autoload'), 'Foo_');