【问题标题】:Zend Framework 2 autoloadingZend Framework 2 自动加载
【发布时间】:2012-09-07 02:14:35
【问题描述】:

我刚开始研究 Zend Framework 2(而且对 ZF 来说一般都是新手),在 user guide 中,他们在添加新模块时使用自动加载。然而,我发现这个解释对于一个菜鸟来说是相当具有挑战性的。他们正在模块目录中添加一个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];
    }
}

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

由于我们处于开发阶段,我们不需要通过类映射加载文件, 所以我们为类映射自动加载器提供了一个空数组。

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

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

【问题讨论】:

  • Zend 的设计太过于荒谬了。
  • 当然。但我认为,如果你找到解决方法,它实际上真的很强大。像 Magento。
  • 我在工作中使用它,它有起有落。不过我更喜欢 Kohana,并使用我可能需要的任何 Zend 库。抱歉@andy124,还没用过2,不好意思劫持了你的问题。
  • ZF2 与 ZF1 完全不同,至少在将其用作应用程序时是这样。不确定我是否喜欢它,但我正在努力学习它。
  • @wes 别担心。我实际上同意你的看法,即使我还是新手。学习曲线就像攀登珠穆朗玛峰,尤其是使用 ZF2。 ZF1 似乎更简单,尽管它有缺陷。我对 ZF2 的最初印象是有人在想“嘿,这会超级酷”,而不是让事情变得更简单。追求完美和专业发展并没有错,但从 ZF1 到 ZF2 似乎在使用起来很容易方面发生了根本性的变化。话虽如此,我确实喜欢关注 ZF2 和命名空间中的模块。

标签: php zend-framework2 zend-autoloader


【解决方案1】:

类图用于向 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(像我一样;),无需担心太多。

【讨论】:

  • 谢谢。你写的关于 ClassMapAutoloader 的内容在你的例子中是有意义的,但我不确定为什么数组中的键是Zend\Loader\ClassMapAutoloader。该值指的是一个甚至不是类的 PHP 文件;它只是返回一个数组。我的猜测是它告诉ClassMapAutoloader 在该文件中查找类映射的配置。并不是说我现在会使用它,而是autoload_classmap.php 的目的是仅仅返回一个类名数组作为键和路径作为值?我从您的回答中了解到,这不是必需的,而只是一种优化。
  • Zend\Loader\ClassMapAutoloader 是一个类。请参阅github.com/zendframework/zf2/blob/master/library/Zend/Loader/… 所以它说“使用 ClassMapAutoloader 并给它文件 autoload_classmap.php 作为参数”。然后,自动加载器使用从该文件返回的数组将类映射到特定文件。是不是清楚一点?
【解决方案2】:

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

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

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

  2. 另一方面,标准自动装载机设计用于容纳 “命名空间”和基本目录的列表。做什么是到那时 通过以下方式构建引用但尚未加载的类的路径 将该命名空间的基本目录路径添加到类 名称,以到达类文件的最终绝对路径,即 然后它会尝试包含。您可以快速填充 通过运行 classmap_autoload.php 文件 /path/to/ZF2/bin/classmap_generator.phpzftool.phar 生成 类图。

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

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

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

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

【讨论】:

    【解决方案3】:

    一个 Web 应用程序由许多 PHP 类组成,并且 每个类通常驻留在一个单独的文件中。这介绍了 包括文件的需要。

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

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

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

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

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

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

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

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

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

    Using Zend Framework 2 书中很好地解释了 Zend Framework 2 中自动加载的概念。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多