热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在ZendFramework中自动加载

自动加载是一种机制,这种机制可以在你的PHP代码中无需手动设置依赖的文件。每一个?thePHP自动加载手册中都强调,一旦自动加载器被定

介绍
自动加载是一种机制,这种机制可以在你的PHP代码中无需手动设置依赖的文件。每一个 ? the PHP自动加载手册中都强调,一旦自动加载器被定义,它“在你试图使用一个还没被定义的类或接口时将被自动调用”
使用自动加载,你无需担心一个类在你的项目中的什么地方。使用良好定义的自动加载,你无需担心一个类文件相对于当前类文件的什么位置;你只要简单的使用这个类,自动加载器将会执行文件查找任务。
另外,自动加载,因为它直到最后一刻才载入并确信匹配只出现一次,是一次巨大的性能提升——特别是在你部署之前如果花时间清除require_once()调用的时候
ZendFramework鼓励使用自动加载,并提供许多工具提供库代码和应用程序代码的自动加载。这个教程覆盖了这些工具,也告诉你如何高效的使用它们。
目标与设计
类的命名约定
为了明白ZendFramework中的自动加载,首先你需要明白类名和类文件的关系。
ZendFramework从PEAR中借鉴了一个思想,即类名和文件系统是一个1:1的关系。为了解决文件路径,简单的将下划线”_”替换为目录分隔 符,然后加上后缀“.php”。比如,“Foo_Bar_Baz”将对应文件系统中的”Foo/Bar/Baz.php”。假设该类也可以通过PHP的 include_path设置来解决,它允许include()和require()在include_path中通过相对路径寻找文件名
另外,每一个PEAR及PHP项目,我们使用并推荐为你的代码使用供应商(vendor)或者项目前缀。这意味着你写的所有类将分享同一个类前缀;比 如,在ZendFramework 中的所有代码有“Zend_”前缀。这个命名约定帮助防止命名冲突。在ZendFramework中,我们经常称之为“命名空间”前缀;注意不要把它与 PHP的本地命名空间混淆(be careful not toconfuse it with PHP’s native namespace implementation)。
ZendFramework在内部遵循这些简单的规则。我们的代码标准鼓励你这样做,就像对所有的库代码一样。
自动加载器的协定和设计
Zend Framework的自动加载支持,首先由Zend_Loader_Autoloader提供,有下面的目标和设计元素:
·提供命名空间匹配。如果类的命名空间前缀不在注册的命名空间列表中,则立即返回FALSE。这样就可以比较乐观的匹配,就像会退到其他的自动加载器 (Thisallows for more optimistic matching, as well as fallback to otherautoloaders.)
·允许自动加载器作为一个备份的自动加载器。在一个团队可能分布很广泛,或者使用一个未确定的命名空间前缀设置的情况下,自动加载器应该仍然被设置的以便它试图去匹配任何命名空间前缀。注意,这种做法是不推荐的,因为它会导致不必要的查找
·允许触发错误抑制。我们感觉到——伟大的PHP社区也是这样的——错误抑制是一个坏主意。它昂贵并且覆盖非常真实的应用程序问题。所以,默认情况下,它应该是关的。然而,如果开发者坚持打开它,我们也允许这么做。
·允许指定为自动加载自定义回调。一些开发者不想去使用Zend_Loader::loadClass()去自动加载,但是仍然想去使用ZendFramework的机制。Zend_Loader_Autoloader允许为自动加载指定一个候选的回调
·允许操作SPL自动加载链。这样做的目的是允许指定另外的自动加载器——比如,类的资源加载器没有与文件系统有1:1的映射关系——在主ZendFramework自动加载器之前或之后被注册
自动加载器的基本用法
既然我们已经懂得了什么是自动加载,并懂得了Framework自动加载解决办法的目标和设计。下面让我们开看看怎么去使用Zend_Loader_Autoloader。
在最简单的情况下,你只需要require这个类,然后实例化它,因为Zend_Loader_Autoloader是一个单态(singleton)的(因为SPL自动加载器是一个单个资源的原因),我们使用getInstance()去获取一个实例。
require_once ‘Zend/Loader/Autoloader.php’;
Zend_Loader_Autoloader::getInstance();
默认情况下,这将允许你载入任何带有”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作为后备自动加载器时,我们不推荐这样做。
内部的,Zend_Loader_Autoloader 使用Zend_Loader::loadClass()来导入类。那个方法使用include()试图导入给定的类文件,如果不成功include()将 返回一个布尔量FALSE,而且发布一个PHP警告。后者实际上可能会导致一些问题:
如果display_errors是启用的,警告将包含在输出中
一来你已经选择的error_reporting级别,它可能也会弄乱你的日志
你能够压制错误信息(Zend_Loader_Autoloader文档详细介绍这个),但是注意当display_errors是启用的,压制仅仅是相关的;错误日志将也会总是显示消息。因为这些原因,我们推荐总是设置能被自动加载器意识到的命名空间前缀
注: 命名空间前缀vs PHP 命名空间
在写这个教程的时候,PHP5.3已经发布了,在这个版本下,PHP现在已经官方支持命名空间了。
然而,Zend Framework在日期上早于PHP5.3建立,命名空间同样也是这样。在ZendFramework中,我们指的“命名空间”是实践上的命名空间,即 带有厂商(vendor)“命名空间”为前缀的类。举例来说,所有的ZendFramework类名称都以“Zend_”为前缀——那就是我们的厂商 (vendor)“命名空间”
ZendFramework计划在将来版本中的自动加载器中提供本地PHP命名空间支持。并且,它的自己的library将在2.0.0版本中使用命名空间
如果你有一个希望使用Zend Frameworkd自定义的自动加载器——也许你也使用一个第三方库中的自动加载器——你可以使用Zend_Loader_Autoloader的 pushAutoloader()和unshiftAutoloader()方法来管理。这些方法将相应的在后面或前面(appendor prepend)添加自动加载器到一个被称为前执行Zend Framework的内部自动载入机制链(These methodswill append or prepend, respectively, autoloaders to a chain thatis called prior to executing Zend Framework’s internal autoloadingmechanism)。这种方法具有以下优点:
每种方法接受可选的第二个参数:类命名空间前缀。这可以用来指示给定的自动加载器应该仅仅在寻找带有指定类前缀的类时被使用。如果处理的类没有那个前缀,自动加载器将被跳过——这将导致性能改进
如果你需要操作spl_autoload()的注册表,任何自动加载器即指向实例方法的回调可能会造成问题(any autoloadersthat are callbacks pointing to instance methods can poseissues),因为spl_autoload_functions()不返回确切的同样回调。Zend_Loader_Autoloader没 有那样的限制。
管理这种方式的自动加载器可以使任何有效的PHP回调(Autoloaders managed this way may be anyvalid 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_’);
资源自动加载
如果你通读autoloader的设计目标,在那节的最后一点指出解决方法应包括这个情况。ZendFramework用Zend_Loader_Autoloader_Resource做这些事情
资源仅仅是一个对应组件命名空间(其加在自动加载器命名空间之后)的名字和路径(其是相对于自动加载器基路径)。在动作中,我们将象下面这样做:
$loader = new Zend_Application_Module_Autoloader(array(
‘namespace’=> ‘Blog’,
‘basePath’  => APPLICATION_PATH .’/modules/blog’,
));
一旦你在合适的位置有了加载器,你就需要将许多的它知道的资源类型通知它(you then need to inform it ofthe various resource types it’s awareof)。这些资源类型是简单的子树(subtree)和前缀的配对

举例来说,考虑一下下面的树
path/to/some/resources/
|– forms/
|   `–Guestbook.php       // Foo_Form_Guestbook
|– models/
|   |– DbTable/
|  |   `–Guestbook.php   // Foo_Model_DbTable_Guestbook
|   |–Guestbook.php       // Foo_Model_Guestbook
|   `–GuestbookMapper.php  //Foo_Model_GuestbookMapper
我们第一步是创建资源加载器:
$loader = new Zend_Loader_Autoloader_Resource(array(
‘basePath’  =>’path/to/some/resources/’,
‘namespace’=> ‘Foo’,
));
下一步,我们需要去定义一些资源类型。
Zend_Loader_Autoloader_Resourse::addResourceType()有三个参数:资源“类型”(任意字符串)、基路 径下的可能存在资源类型的路径和为资源类型使用的组件前缀。在上面的树中,我们有三个资源类型:表单(在“forms”子目录中,带有一个组件前缀 “Form”)、模型(在“models”子目录中,带有一个组件前缀“Model”)和dbtable(在“models/DbTable”子目录中, 带有“Model_DbTable”组件前缀)。我们像下面这样定义它们
$loader->addResourceType(‘form’, ‘forms’,'Form’)
->addResourceType(‘model’, ‘models’, ‘Model’)
->addResourceType(‘dbtable’, ‘models/DbTable’,'Model_DbTable’);
一旦定义了,我们能够简单的使用下面的类
$form     = new Foo_Form_Guestbook();
$guestbook = new Foo_Model_Guestbook();
注:模块(module)资源的自动加载
ZendFramework的MVC层鼓励使用“模块(modules)”,它是在你的站点中自包含的应用程序。默认情况下模块典型的有许多资源类 型,ZendFramework甚至为模块推荐一个标准的目录布局。资源自动载入器因此在这个范例中是非常有用的——那么的有用以至于,当你为你的模块 (module)创建扩展于Zend_Application_Module_Bootstrap的一个引导类(bootstrapclass)时,默认 情况下它们是启用的。更多的信息请参考Zend_Loader_Autoloader_Module 文档。
结论
ZendFramework鼓励使用autoloading,甚至在Zend_Application中默认初始化它。希望这个教程最大程度的提供给你需 要使用的Zend_Loader_Autoloader的信息以及通过附加自定义的自动加载器或者资源自动加载器来扩展它的功能。


推荐阅读
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • MVC设计模式的介绍和演化过程
    本文介绍了MVC设计模式的基本概念和原理,以及在实际项目中的演化过程。通过分离视图、模型和控制器,实现了代码的解耦和重用,提高了项目的可维护性和可扩展性。详细讲解了分离视图、分离模型和分离控制器的具体步骤和规则,以及它们在项目中的应用。同时,还介绍了基础模型的封装和控制器的命名规则。该文章适合对MVC设计模式感兴趣的读者阅读和学习。 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • Todayatworksomeonetriedtoconvincemethat:今天在工作中有人试图说服我:{$obj->getTableInfo()}isfine ... [详细]
  • 从零基础到精通的前台学习路线
    随着互联网的发展,前台开发工程师成为市场上非常抢手的人才。本文介绍了从零基础到精通前台开发的学习路线,包括学习HTML、CSS、JavaScript等基础知识和常用工具的使用。通过循序渐进的学习,可以掌握前台开发的基本技能,并有能力找到一份月薪8000以上的工作。 ... [详细]
  • 数据库锁的分类和应用
    本文介绍了数据库锁的分类和应用,包括并发控制中的读-读、写-写、读-写/写-读操作的问题,以及不同的锁类型和粒度分类。同时还介绍了死锁的产生和避免方法,并详细解释了MVCC的原理以及如何解决幻读的问题。最后,给出了一些使用数据库锁的实际场景和建议。 ... [详细]
  • ps:写的第一个,不足之处,欢迎拍砖---只是想用自己的方法一步步去实现一些框架看似高大上的小功能(比如说模型中的toArraytoJsonsetAtt ... [详细]
  • 今天写一篇blog,已经多长时间没有更了,两个月了吧,没办法,现在银行开发,不能连外网,天天用虚拟机,真烦今天随手写点东西,主要是这两天对于springboot启动的分析,有所领悟 ... [详细]
  • 初识java关于JDK、JRE、JVM 了解一下 ... [详细]
  • ElasticSearch成功安装完毕。 测试数据添加出现{  error:{    root_cause ... [详细]
  • MVC中的自定义控件
    怎么样创建自定义控 ... [详细]
  • 基于SpringBoot打造在线教育系统(6)– 二级分类模块UI篇
    这一节来做二级分类,为了快速开发,一级分类只做新增,暂时不考虑修改和删除,如果一定要删,就去数据库删吧。我们接下来,需要通过一级分类,获取所有的二级分类。开始 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 一、Struts2是一个基于MVC设计模式的Web应用框架在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts2优点1、实现 ... [详细]
  • Asp.Net MVC 测试应用程序
    建立一个Asp.NetMVC项目的时候,如果选择建立测试项目,那么系统会为我们建立一个项目所对应的测试项目。包含了Controller文件夹中对应的Controller单元测试文件, ... [详细]
author-avatar
太阳之神sqh
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有