我刚刚开始关注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];
}
}
由于表现,这似乎很聪明。我希望我刚才写的是正确的。基于此,我试图从第一个代码片段中弄清楚getAutoloaderConfig()
中发生了什么,但我很困惑。似乎这个方法返回的数组用于AutoloaderFactory::factory()
,但我不确定是什么用途。使用选项实例化自动加载器,但确实是这样,我不确定。我想数组的第二个条目指定在哪里找到模块命名空间的源文件 - 至少这是我的猜测。然而,我第一个条目并不确定。在用户指南中,它说明了以下内容:
在开发过程中,我们不需要通过类图加载文件, 所以我们为classmap autoloader提供了一个空数组。
该文件只返回一个空数组。我不确定这个ClassMapAutoloader的目的是什么。
对不起,如果我的观点不清楚;基本上我想弄清楚getAutoloaderConfig()
中发生了什么以及mymodule/autoload_classmap.php
用于什么。如果有人能够对此有所了解,那将非常感激!
答案 0 :(得分:21)
classmap用于向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(像我一样),就没什么可担心的。
答案 1 :(得分:8)
ZF2有许多可用的自动加载器。
最常见的2个(或开发人员以任何速率直接与之互动的2个)是Zend\Loader\ClassMapAutoloader
和Zend\Loader\StandardAutoloader
。
类图自动加载器通常用于模块级别
提供简单但快速的数组查找机制。它已配置
使用关键数组key => value
对关联数组
表示类,以及表示文件名的值
它定义了这个类。
另一方面,标准自动装载机设计用于存放
“名称空间”和基目录的列表。那是做什么的
构建引用的类的路径,但尚未加载
将该命名空间的基本目录路径添加到该类
name,到达类文件的最终绝对路径,哪个
然后它试图包括。你可以快速填充
classmap_autoload.php文件通过运行
生成/path/to/ZF2/bin/classmap_generator.php
或zftool.phar
类映射
Zend\Loader\AutoloaderFactory
旨在管理各种自动加载器,并确保没有冲突。当然,最终所有自动加载功能都利用PHP SPL自动加载。
getAutoloaderConfig()
的目的是向自动加载器工厂识别哪个自动加载器可用于此模块的命名空间。
在上面显示的示例中,按优先顺序,这将是classmap自动加载器,后跟标准自动加载器。如果您不希望为该模块使用classmap自动加载器,请简单地从getAutoloaderConfig()
返回的数组中删除引用。
保留方法名称getAutoloaderConfig()
。如果定义了此方法,则在模块初始化过程中,将附加一个侦听器(Zend\ModuleManager\AutoloaderListener
),该侦听器将检索此方法返回的配置,并将其添加到统一配置中。
答案 2 :(得分: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类。这是使用getAutoloaderConfig()
类的Module
方法进行的。
ZF2有一个名为Zend\Loader
的特殊组件,它包含实现
两种常用的自动加载器类:标准自动加载器(Zend\Loader\StandardAutoloader
)
和类映射自动加载器(Zend\Loader\ClassMapAutoloader
)。
基于ZF2的应用模块符合PSR-0标准的事实使得可以使用标准自动加载器。
类地图自动装载机可用作标准自动装载机的更快替代品。 这个自动加载器希望您传递一个类映射数组。该类的每个 key => value 对 map分别是包含该类的PHP文件的类名和路径。
在Using Zend Framework 2书中很好地解释了Zend Framework 2中自动加载的概念。