12

我刚开始研究 Zend Framework 2(一般来说是 ZF 的新手),在用户指南中,他们在添加新模块时使用自动加载。然而,我发现这个解释对于一个菜鸟来说是相当具有挑战性的。他们正在Module.php模块目录中添加一个文件,其中包含以下代码:

public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\ClassMapAutoloader' => array(
                __DIR__ . '/autoload_classmap.php',
            ),
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
            ),
        );
    }

现在我做了一些挖掘,试图弄清楚这个自动加载是怎么回事。据我了解,自动加载使用spl_autoload_register()并且是一种避免require_once()在代码中无处不在的方法。因此,当尝试使用未定义的类时,autoload()将运行已注册的方法,该方法仅进行数组查找并包含如下所示的文件(如果已添加)。

// Zend/Loader/ClassMapAutoloader.php
public function autoload($class)
{
    if (isset($this->map[$class])) {
        require_once $this->map[$class];
    }
}

由于性能,这似乎很聪明。我希望我刚才写的是正确的。基于此,我试图从第一个代码片段中弄清楚发生了什么getAutoloaderConfig(),但我很困惑。似乎此方法返回的数组用于AutoloaderFactory::factory(),但我不确定用于什么目的。似乎用选项实例化自动加载器,但具体是做什么的,我不确定。我猜数组的第二个条目指定了在哪里可以找到模块名称空间的源文件——至少这是我的猜测。然而,我不确定的第一个条目。在用户指南中,它说明了以下内容:

由于我们正在开发中,我们不需要通过类映射加载文件,因此我们为类映射自动加载器提供了一个空数组。

该文件只返回一个空数组。我不确定这个 ClassMapAutoloader 的目的是什么。

对不起,如果我的观点不清楚;基本上我试图弄清楚发生了什么getAutoloaderConfig()以及mymodule/autoload_classmap.php用于什么。如果有人可以对此有所了解,那将不胜感激!

4

3 回答 3

21

类图用于向 PHP 显示类的最直接方式。它本质上是在说“你正在寻找的A\Class\Youre\Looking\For,不要再看这个文件了:xyz.php。这将被表达为:

return array(
    'A\Class\Youre\Looking\For' => ___DIR__.'/xyz.php'
)

没有它,PHP 必须运行整个自动加载器链,这可能会非常昂贵。为什么它说“我们正在开发中”?因为类映射文件通常由一些脚本在生产服务器上生成。基本上,现在不要太担心它。是微优化...

getAutoloaderConfig()方法只是为您在真正高级的应用程序中提供一些灵活性。大多数情况下,您可以只使用 SkeletonApplication 和 SkeletonModule 的样板代码,不用管它。真的,你现在甚至可以杀死这个'Zend\Loader\ClassMapAutoloader' => array(__DIR__ . '/autoload_classmap.php',)部分。

这只是未来改进的一个钩子,如果您刚开始使用 ZF2(像我一样;),无需担心太多。

于 2012-09-13T22:39:16.513 回答
8

ZF2 有许多可用的自动装载机。

最常见的 2 个(或开发人员直接与之交互的 2 个)是Zend\Loader\ClassMapAutoloaderZend\Loader\StandardAutoloader

  1. classmap 自动加载器通常在模块级别使用,以提供简单但快速的数组查找机制。它配置了一个关联数组key => value对,键代表类,值代表定义类的文件名。

  2. 另一方面,标准自动加载器旨在保存“命名空间”和基本目录的列表。然后通过将该命名空间的基目录路径添加到类名前面来构建引用但尚未加载的类的路径,以到达类文件的最终绝对路径,然后尝试包括。/path/to/ZF2/bin/classmap_generator.php您可以通过运行或zftool.phar生成类映射来快速填充 classmap_autoload.php 文件 。

Zend\Loader\AutoloaderFactory旨在管理各种自动装载机,并确保没有冲突。当然,最终,所有自动加载功能都利用 PHP SPL 自动加载。

的目的getAutoloaderConfig()是向自动加载器工厂识别哪些自动加载器可用于该模块的命名空间。

在上面显示的示例中,按照优先顺序,类映射自动加载器,然后是标准自动加载器。如果您不想为该模块使用类映射自动加载器,只需从getAutoloaderConfig().

方法名称getAutoloaderConfig()是保留的。如果定义了此方法,则在模块初始化过程中,将Zend\ModuleManager\AutoloaderListener附加一个侦听器 (),该侦听器检索此方法返回的配置,并将其添加到合并配置中。

于 2013-05-06T10:25:53.700 回答
3

一个 Web 应用程序由许多 PHP 类组成,每个类通常位于一个单独的文件中。这引入了包含文件的需要。

随着应用程序大小的增加,可能很难包含每个需要的文件。Zend Framework 2 本身包含数百个文件,以这种方式加载整个库及其所有依赖项可能非常困难。此外,在执行生成的代码时,PHP 解释器将花费 CPU 时间来处理每个包含的文件,即使您没有创建其类的实例。

为了解决这个问题,在 PHP 5.1 中,引入了类自动加载功能。PHP 函数spl_autoload_register()允许您注册一个自动加载器函数。对于复杂的网站,您甚至可以创建多个链接在堆栈中的自动加载器函数。

在脚本执行期间,如果 PHP 解释器遇到尚未定义的类名,它会依次调用所有已注册的自动加载器函数,直到自动加载器函数包含该类或引发“未找到”错误。这允许“延迟”加载,当 PHP 解释器仅在类调用时处理类定义时,当它确实需要时。

因为每个库的供应商都使用自己的代码命名和文件组织约定,所以您必须为每个依赖库注册不同的自定义自动加载器函数,这很烦人(实际上这是一项不需要的工作)。为了解决这个问题,引入了 PSR-0 标准。

PSR-0 标准(PSR 代表 PHP 标准推荐)定义了应用程序或库必须遵循的 推荐代码结构,以保证自动加载器的互操作性。

Web 应用程序的每个模块都注册了一个自动加载器,这使得自动加载模块中的任何 PHP 类成为可能。这是使用类的getAutoloaderConfig()方法完成的Module

ZF2 有一个名为 的特殊组件Zend\Loader,其中包含两个常用自动加载器类的实现:标准自动加载器 ( Zend\Loader\StandardAutoloader) 和类映射自动加载器 ( Zend\Loader\ClassMapAutoloader)。

基于 ZF2 的应用模块符合 PSR-0 标准这一事实使得使用标准自动加载器成为可能。

类映射自动加载器可以用作标准自动加载器的更快替代品。这个自动加载器希望您向它传递一个类映射数组。类映射的每个key=>value对分别是类名和包含该类的 PHP 文件的路径。

Zend Framework 2 中自动加载的概念在《使用 Zend Framework 2》一书中得到了很好的解释。

于 2014-01-25T06:22:00.493 回答