标签归档:自动装载

Yaf中自动装载

Yaf中提供了Yaf_Loader来装载资源。实现单利模式。一般是由Yaf_Application负责初始化的。初始化的过程就是调用Yaf_Loader的getInstance()方法:

public static Yaf_Loader Yaf_Loader::getInstance( string  $local_library_directory = NULL , string  $global_library_directory = NULL );

默认传递两个路径信息,Yaf_Application初始化时把$local_library_directory赋值为配置文件中的ap.library,$global_library_directory赋值为PHP配置中的ap.library。换句话说就是这个Loader就搜索这两个目录,如果有第三方的类需要自动装载,放入这两个目录即可。

Yaf_Loader提供import方法,可以导入任意位置的文件(类似include)。
Yaf_Loader提供registerLocalNamespace方法注册本地名空间,意思就是在本地类库目录加载对应名空间(不去全局类库目录)。在其它的自动装载的实现方案中,注册命名空间可以让Loader快速定位到代码位置(比如$loader->set(“Zend”,”/library”))。Yaf_Loader无法指定一个命名空间对应一个路径。

Yaf_Loader自然使用了PHP中的spl_autoload实现。在Yaf扩展可用配置中(写入PHP的配置),有配置项yaf.use_spl_autoload,默认值为0(关闭),文档说明:开启的情况下, Yaf在加载不成功的情况下, 会继续让PHP的自动加载函数加载, 从性能考虑, 除非特殊情况, 否则保持这个选项关闭,意思就是说,如果关闭,后续注册到spl_autoload的自动装载函数将不生效(被剥夺了),如果要使用第三方的自动装载方案,务必把0改为1。

Yaf_Loader把类转载限定到两个目录,大部分情况下,都能满足需要,不过如果使用的第三方类库比较多,要管理它们的版本,就需要引入包管理器。

Yaf框架还需要映射models,controllers(分模块也一样),内部映射细节应该是根据类名来获取文件名然后import,在models中的类也可以添加命名空间,但是最终的类名必须添加Model后缀(控制器是Controller),实例化一个Model是一个显式的可控的操作,但是实例化一个控制器是框架自动完成的操作,所以控制器添加命名空间是不妥的,至少在Yaf中不妥。

Yaf中可以使用反斜杠方式使用Yaf的类,不过需要在PHP配置中添加:

yaf.use_namespace = 1

这样,Yaf_Application就可以以Yaf\Application来用,不过要注意的是,最后以Abtract结尾的类,比如Yaf_Bootstrap_Abstract,只能改为Yaf\Bootstrap_Abstract,最后的下划线不能换掉,否则就是语法错误,就把Bootstrap_Abstract整体看成一个类名就好了。当然,如果要用到这些类,比如用到Yaf\Application,先use一下,然后接下来就可以直接使用Application了。

一份实例:

<?php
use Yaf\Application;
use Yaf\Bootstrap_Abstract as BootstrapAbstract;
use Yaf\Dispatcher;
use Yaf\Route\Regex;
use Zend\Db\Adapter\Adapter;

class Bootstrap extends BootstrapAbstract {
	private $_config;

	public function _init(Dispatcher $dispatcher) {
		$this->_config = Application::app()->getConfig();
		Registry::set('config', $this->_config);

		///
		if($this->_config->application->showError){
			error_reporting (-1);
			ini_set('display_errors','On');
		}
		
// 		$library = ROOT_PATH.'/library';
// 		$actions = APPLICATION_PATH.'/actions';
// 		$models  = APPLICATION_PATH.'/models';
// 		//get_include_path()
// 		$includePath = array(
// 			$library,
// 			$actions,
// 			$models
// 		);
// 		set_include_path(implode(PATH_SEPARATOR, $includePath));

// 		if(file_exists(ROOT_PATH.'/vendor/autoload.php')){
// 			$loader = include ROOT_PATH.'/vendor/autoload.php';
// 		}else{
// 			exit("Composer Autoload Failed. ");
// 		}
// 		$loader->setUseIncludePath(true);
// 		$loader->setPsr4("Zend\\",$library.'/zf2_psr4');
// 		Registry::set('loader', $loader);
		
		$dispatcher->autoRender(FALSE);
		
		Registry::set('adapter',function(){
			$mysqlMasterConfig = $this->_config->mysql->master->toArray();
			$adapter = new Adapter($mysqlMasterConfig);
			return $adapter;
		});
	}
	
	public function _initRoutes() {
		//Dispatcher::getInstance()->getRouter()->addRoute("xxx", new Regex(,,));
	}
		
	public function _initPlugin(Dispatcher $dispatcher) {
// 		$authPlugin = new AuthPlugin();
// 		$dispatcher->registerPlugin($authPlugin);
	}
	
	public function _initLayout() {
// 		$layout = new Zend_Layout();
	
// 		$layoutPath = APPLICATION_PATH . '/layouts';
// 		if(isset($this->_config->application->layoutPath)) {
// 			$layoutPath = $this->_config->application->layoutPath;
// 		}
	
// 		$layout->setLayoutPath($layoutPath);
	
// 		$layout->getView()->headLink()->appendStylesheet('/css/jquery-ui.min.css');
// 		$layout->getView()->headScript()->appendFile('/js/jquery.min.js');
// 		$layout->getView()->headScript()->appendFile('/js/jquery-ui.min.js');
	
// 		Yaf_Registry::set('layout', $layout);
	}
}

Zend Framework自动转载之Zend_Load_Autoloader

Zend Framework对于自动转载类提供了Zend_Loader_Autoloader类(对于资源加载,提供了Zend_Loader_Autoloader_Resource类),它实现单态模式,查看构造函数:

    protected function __construct()
    {
        spl_autoload_register(array(__CLASS__, 'autoload'));
        $this->_internalAutoloader = array($this, '_autoload');
    }

可以看到构造函数中使用spl_autoload_register()注册当前类的autoload函数作为自动装载函数(实际这里的代码是对SPL的自动装载进行了一层封装)。使用如下代码测试:

// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));

require_once 'Zend/Loader/Autoloader.php';
// 获取Zend_Loader_Autoloader类对象,然后打印它,看初始化的内容
$loader = Zend_Loader_Autoloader::getInstance();
print_r($loader);

//以下是对象的输出
Zend_Loader_Autoloader Object
(
    [_autoloaders:protected] => Array
        (
        )

    [_defaultAutoloader:protected] => Array
        (
            [0] => Zend_Loader
            [1] => loadClass
        )

    [_fallbackAutoloader:protected] => 
    [_internalAutoloader:protected] => Array
        (
            [0] => Zend_Loader_Autoloader Object
 *RECURSION*
            [1] => _autoload
        )

    [_namespaces:protected] => Array
        (
            [Zend_] => 1
            [ZendX_] => 1
        )

    [_namespaceAutoloaders:protected] => Array
        (
        )

    [_suppressNotFoundWarnings:protected] => 
    [_zfPath:protected] => 
)

可以看到,默认初始化了_namespaces为Array([Zend_]=>1, [ZendX_]=>1) 和 _defaultAutoloader 为Array([0]=>Zend_Loader,[1]=>loadClass) 和 _internalAutoloader为Array([0] => Zend_Loader_Autoloader Object [1] => _autoload)。_internalAutoloader就是默认的装载器,实际它最终还是调用_defaultAutoloader设置的函数装载类(在类未提供装载函数时)。

命名空间可以使用registerNamespace($namespace)、unregisterNamespace($namespace)、getRegisteredNamespaces()来管理命名空间,实际是在操作_namespaces字段。注意,并不是注册了名空间,名空间的类就能自动装载(符合ZF规范的类组织才能),默认如果没有为名空间指定装载器,则使用_internalAutoloader,有几个相关函数unshiftAutoloader($callback, $namespace = ”)、pushAutoloader($callback, $namespace = ”)、removeAutoloader($callback, $namespace = null),这几个函数如果指定了$namespace就可以为具体的名空间指定专用的装载器。这个方法操作_namespaceAutoloaders(同时也会操作_autoloaders,它保存全部的自定义函数),比如为”My_”命名空间指定自动装载函数(意思是My_这个命名空间的类使用myLoad函数装载,对于其它的名空间如果没有指定就使用默认的):

$loader = Zend_Loader_Autoloader::getInstance();
$loader->pushAutoloader("myLoad","My_");
print_r($loader->getNamespaceAutoloaders("My_"));
//以下是输出
Array([0]=> myLoad)

以上使用了getNamespaceAutoloaders($namespace)获取名空间的类装载器,如果返回空数组,则表示名空间没有指定装载函数(那么框架将使用默认装载器装载类)。

另外,setAutoloaders(array $autoloaders) 和 getAutoloaders()操作_autoloaders,_autoloaders保存了全部自定义的自动装载函数,它一般都和$_namespaceAutoloaders一致,除非明确调用以上函数操作_autoloaders。

例子,让My_命名空间的类自动装载:

//在libray目录下建立My目录,里面放入My_MyClass.php
class My_MyClass{
    public function __construct(){
		echo "My_Class object.";
	}
}

//在运行脚本中
$loader = Zend_Loader_Autoloader::getInstance();
$loader->registerNamespace("My_");
$myclass = new My_MyClass();
//输出 My_Class object.  说明类正确加载,对象生成。

如非明确指定装载器,否则都使用默认的实现,而默认的实现主要逻辑体系在autoload($class)方法的实现:

    public static function autoload($class)
    {
        $self = self::getInstance();
        foreach ($self->getClassAutoloaders($class) as $autoloader) {
            if ($autoloader instanceof Zend_Loader_Autoloader_Interface) {
                if ($autoloader->autoload($class)) {
                    return true;
                }
            } elseif (is_array($autoloader)) {
                if (call_user_func($autoloader, $class)) {
                    return true;
                }
            } elseif (is_string($autoloader) || is_callable($autoloader)) {
                if ($autoloader($class)) {
                    return true;
                }
            }
        }

        return false;
    }

getClassAutoloaders($class)返回自动转载器的列表,分三种情况:
1 如果这个自动装载器实现了Zend_Loader_Autoloader_Interface接口,这调用这个对象的autoload()函数装载类。
2 如果是数组,这个情况一般就是指Array([0] => Zend_Loader_Autoloader Object [1] => _autoload),它被传入call_use_func()函数,那么这个_autoload将被执行,它执行时实际调用Zend_Loader类的loadClass()函数(_defaultAutoloader指定的内容)。注意,可以为名空间设置一个或多个没有关联下标的装载器(一般都没有必要),这些装载器在当名空间没有匹配到装载器时会被使用,也可以不指定,则使用默认的。
3 直接指定的回调函数

在使用Zend Framework构建的MVC项目中,自动装载器是在什么地方初始化的呢。 每个应用都是从一个Application开始的:

// Zend_Application类的构造函数
    public function __construct($environment, $options = null)
    {
        $this->_environment = (string) $environment;

        require_once 'Zend/Loader/Autoloader.php';
        $this->_autoloader = Zend_Loader_Autoloader::getInstance();

        if (null !== $options) {
            if (is_string($options)) {
                $options = $this->_loadConfig($options);
            } elseif ($options instanceof Zend_Config) {
                $options = $options->toArray();
            } elseif (!is_array($options)) {
                throw new Zend_Application_Exception('Invalid options provided; must be location of config file, a config object, or an array');
            }

            $this->setOptions($options);
        }
    }

从这个构造函数中可以清楚的知道,Zend_Loader_Autoloader的实例赋值给了$this->_autoloader,可以通过getAutoloader()方法获取这个实例,然后操作这个对象。

更多内容可以参考源码 或 参考文档。

永久链接: http://blog.ifeeline.com/197.html

Zend Framework中的自动装载

Autoloading is a mechanism技巧 that eliminates排除 the need to manually require dependencies依赖关系 within your PHP code. Per the PHP autoload manual, once an autoloader has been defined, it “is automatically called in case you are trying to use a class or an interface which hasn’t been defined yet.” 一旦一个autoloader已经定义,当试图使用一个当前没有定义的类或者接口时它就会被自动调用。

Using autoloading, you do not need to worry about where a class exists in your project. 使用autoloading,你不需要担心一个类放在项目的什么地方。 With well-defined autoloaders, you do not need to worry about where a class file is relative to the current class file; you simply use the class, and the autoloader will perform the file lookup.

Additionally, autoloading, because it defers推迟 loading to the last possible moment and ensures that a match only has to occur once, can be a huge巨大的 performance boost提高 — particularly if you take the time to strip out require_once() calls before you move to deployment.

Zend Framework encourages鼓励 the use of autoloading, and provides several tools to provide autoloading of both library code as well as application code. This tutorial covers these tools, as well as how to use them effectively有效地.

Goals and Design 目标与设计
1 Class Naming Conventions类命名惯例
To understand autoloading in Zend Framework, first you need to understand the relationship between class names and class files. 要理解Zend Framework中的自动装载,首先需要理解类名和类文件之间的关系。

Zend Framework has borrowed an idea from PEAR, whereby class names have a 1:1 relationship with the filesystem. Zend Framework从PEAR那里借用了方法,类名和文件系统的关系是1比1的关系。 Simply put, the underscore character (“_”) is replaced by a directory separator in order to resolve the path to the file, and then the suffix “.php” is added. 简单的说,为了分解路径到文件,使用下划线替换了目录分隔符。 For example, the class “Foo_Bar_Baz” would correspond to “Foo/Bar/Baz.php” on the filesystem. The assumption is also that the classes may be resolved via PHP’s include_path setting, which allows both include() and require() to find the filename via a relative path相对路径 lookup on the include_path.

Additionally, per PEAR as well as the PHP project, we use and recommend using a vendor or project prefix for your code.在代码中使用和建议使用一个前缀。 What this means is that all classes you write will share a common class prefix; 这个意味着所有的类共享一个公共的类前缀;for example, all code in Zend Framework has the prefix “Zend_”. This naming convention helps prevent naming collisions.这个命名惯例避免命名冲突。 Within Zend Framework, we often refer to this as the “namespace” prefix; be careful not to confuse it with PHP’s native namespace implementation. 在Zend Framework中,通常把它作为命名空间,不过它跟PHP原生的命名空间是不一样的。

Zend Framework follows these simple rules internally, and our coding standards encourage that you do so as well for all library code.

2 Autoloader Conventions and Design自动转载惯例与设计
Zend Framework’s autoloading support, provided primarily via Zend_Loader_Autoloader, has the following goals and design elements:
Zend Framework自动转载的支持主要通过Zend_Loader_Autoloader提供,它有如下一些目标和设计元素:
•Provide namespace matching. If the class namespace prefix is not in a list of registered namespaces, return FALSE immediately. This allows for more optimistic matching, as well as fallback to other autoloaders. 提供命名空间匹配。如果一个类命名空间前缀没有在注册的命名空间列表中,马上返回FALSE。这样可以更快匹配,以及回退到其它的装载器。
•Allow the autoloader to act as a fallback autoloader. In the case where a team may be widely distributed广泛分布, or using an undetermined未确定的 set of namespace prefixes, the autoloader should still be configurable such that it will attempt to match any namespace prefix. It will be noted, however, that this practice is not recommended, as it can lead to unnecessary lookups. 允许自动转载器扮演一个回调自动转载器。在这种情况下,在一个团队可能广泛分布 或 使用一个未确定的命名空间前缀集合,自动装载器还是可配置,这样它就试图去匹配任意的命名空间前缀。要注意,然而,这种做法是不推荐,因为它可能会导致不必要的查找。
•Allow toggling切换 error suppression禁止. We feel — and the greater PHP community does as well — that error suppression is a bad idea. It’s expensive, and it masks very real application problems. So, by default, it should be off. However, if a developer insists坚持认为 that it be on, we allow toggling it on.
•Allow specifying custom callbacks for autoloading. Some developers don’t want to use Zend_Loader::loadClass() for autoloading, but still want to make use of Zend Framework’s mechanisms. Zend_Loader_Autoloader allows specyfing an alternate callback for autoloading. 允许为自动转载定制回调函数。
•Allow manipulation of the SPL autoload callback chain. The purpose of this is to allow specifying additional autoloaders — for instance, resource loaders for classes that don’t have a 1:1 mapping to the filesystem — to be registered before or after the primary Zend Framework autoloader. 运行维护SPL自动转载回调函数链。这个目的是允许指定另外的装载器,比如,类不是1:1映射到文件系统的资源加载器,在Zend Framework自动转载器之前或之后可以被注册。

Basic Autoloader Usage 基本自动转载器的使用

Now that we have an understanding of what autoloading is and the goals and design of Zend Framework’s autoloading solution, let’s look at how to use Zend_Loader_Autoloader.

In the simplest case, you would simply require the class, and then instantiate it. 要先加载这个类,然后实例化它。 Since Zend_Loader_Autoloader is a singleton (due to the fact that the SPL autoloader is a single resource由于SPL自动装载器是一个单态资源的这一事实), we use getInstance() to retrieve an instance.

require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();

By default, this will allow loading any classes with the class namespace prefixes of “Zend_” or “ZendX_”, as long as they are on your include_path.
默认,这将允许加载任意的以Zend_或ZendX_为命名空间前缀的类,只要它们在include_path中能找到。

What happens if you have other namespace prefixes you wish to use? 当希望使用其它命名空间前缀时将发生什么? The best, and simplest, way is to call the registerNamespace() method on the instance. 最好并且最简单的方法是调用实例的registerNamespace()方法。 You can pass a single namespace prefix, or an array of them: 可以传递一个命名空间前缀或者一个数组:

require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->registerNamespace('Foo_'); //注册名空间
$loader->registerNamespace(array('Foo_', 'Bar_'));

Alternately, you can tell Zend_Loader_Autoloader to act as a “fallback” autoloader. This means that it will try to resolve any class regardless of namespace prefix. 可选的,你可以告诉Zend_Loader_Autoloader去扮演一个回调装载函数。 这意味它将试图去解析任意的类而不管命名空间前缀。

$loader->setFallbackAutoloader(true);

Do not use as a fallback autoloader
While it’s tempting to use Zend_Loader_Autoloader as a fallback autoloader, we do not recommend the practice.
Internally, Zend_Loader_Autoloader uses Zend_Loader::loadClass() to load classes. 在内部,Zend_Loader_Autoloader使用Zend_Loader::loadClass()加载类。 That method uses include() to attempt to load the given class file. 这个方法使用include()去试图加载给定的类文件。 include() will return a boolean FALSE if not successful — but also issues a PHP warning. include()如果不成功将返回FALSE,但是也发出一条PHP警告信息。 This latter fact can lead to some issues: 这一事实可能导致一些问题:
•If display_errors is enabled, the warning will be included in output. 如果display_errors是启用的,这个警告将包含在输出中。
•Depending on the error_reporting level you have chosen, it could also clutter混乱 your logs. 依赖error_reporting的级别,它可能让你的日志变得混乱。

You can suppress禁止 the error messages (the Zend_Loader_Autoloader documentation details this), but note that the suppression is only relevant有关联的 when display_errors is enabled; the error log will always display the messages. For these reasons, we recommend always configuring the namespace prefixes the autoloader should be aware of.

Note: Namespace Prefixes vs PHP Namespaces命名空间前缀与PHP内置的命名空间对比
At the time this is written, PHP 5.3 has been released. With that version, PHP now has official namespace support.
However, Zend Framework predates在它之前 PHP 5.3, and thus namespaces. Within Zend Framework, when we refer to “namespaces”, we are referring to a practice whereby classes are prefixed with a vender “namespace”. As an example, all Zend Framework class names are prefixed with “Zend_” — that is our vendor “namespace 厂商名空间”.

Zend Framework plans to offer native PHP namespace support to the autoloader in future revisions, and its own library will utilize使用 namespaces starting with version 2.0.0. 从2.0.0开始支持PHP原生名空间。

If you have a custom autoloader you wish to use with Zend Framework — perhaps an autoloader from a third-party library you are also using — you can manage it with Zend_Loader_Autoloader’s pushAutoloader() and unshiftAutoloader() methods. These methods will append or prepend, respectively分别地, autoloaders to a chain that is called prior优先的 to executing Zend Framework’s internal autoloading mechanism. This approach offers the following benefits:
•Each method takes an optional second argument, a class namespace prefix.每个方法提供一个可先的第二参数,它指定了类的命名空间前缀。 This can be used to indicate表明 that the given autoloader should only be used when looking up classes with that given class prefix. 这可以用来表明给定的自动装载器只能在当查找有给定类前缀的类时使用。 If the class being resolved does not have that prefix, the autoloader will be skipped — which can lead to performance improvements.
•If you need to manipulate spl_autoload()’s registry, any autoloaders that are callbacks pointing to instance methods can pose引起 issues, as spl_autoload_functions() does not return the exact精确的 same callbacks. Zend_Loader_Autoloader has no such limitation.
Autoloaders managed this way may be any valid 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_');

Resource Autoloading 资源自动加载
Often, when developing an application, it’s either difficult to package classes in the 1:1 classname:filename standard Zend Framework recommends, or it’s advantageous for purposes of packaging not to do so. However, this means you class files will not be found by the autoloader. 类和文件名不是1:1对应,开发中存在这些情况。

If you read through the design goals for the autoloader, the last point in that section indicated that the solution should cover this situation. Zend Framework does so with Zend_Loader_Autoloader_Resource. Zend Framework中使用Zend_Loader_Autoloader_Resource来实现资源自动加载。

A resource is just a name that corresponds to a component namespace (which is appended to the autoloader’s namespace) and a path (which is relative to the autoloader’s base path). 资源仅是一个对组件命名空间相关的名字(它被后加到自动转载器命名空间之后)和路径(它是相关的自动转载器的基路径)In action, you’d do something like this:

$loader = new Zend_Application_Module_Autoloader(array(
	    'namespace' => 'Blog',
	    'basePath'  => APPLICATION_PATH . '/modules/blog',
	));

(Zend_Application_Module_Autoloader 继承自Zend_Loader_Autoloader_Resource)

Once you have the loader in place, you then need to inform it of the various resource types it’s aware of. These resource types are simply pairs of subtree and prefix. 一旦你有了加载器,然后你需要通知它的各种它知道的资源类型。这些资源类型是简单的一对子树和前缀
As an example, consider the following tree:

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

Our first step is creating the resource loader: 

	$loader = new Zend_Loader_Autoloader_Resource(array(
	    'basePath'  => 'path/to/some/resources/',
	    'namespace' => 'Foo',
	));

Next, we need to define some resource types. 接下来需要定义一些资源类型。

Zend_Loader_Autoloader_Resourse::addResourceType() has three arguments: the “type” of resource (an arbitrary string), the path under the base path in which the resource type may be found, and the component prefix to use for the resource type. Zend_Loader_Autoloader_Resourse::addResourceType()有三个参数,资源的类型,资源类型可能查找的在基本路径下的路径, 和为资源类型给定的组件的前缀。 In the above tree, we have three resource types: form (in the subdirectory “forms”, with a component prefix of “Form”), model (in the subdirectory “models”, with a component prefix of “Model”), and dbtable (in the subdirectory “models/DbTable”, with a component prefix of “Model_DbTable”). 在上面给出的例子有三种资源类型,form(在子目录forms中,它的组件前缀时Form) model(在子目录models中,组件前缀时Model) 和dbtable(在子目录models/DbTable,组件前缀是Model_DbTable)。 We’d define them as follows:

$loader->addResourceType('form', 'forms', 'Form')
	       ->addResourceType('model', 'models', 'Model')
	       ->addResourceType('dbtable', 'models/DbTable', 'Model_DbTable');

Once defined, we can simply use these classes: 

	$form      = new Foo_Form_Guestbook();
	$guestbook = new Foo_Model_Guestbook();

Note: Module Resource Autoloading
Zend Framework’s MVC layer encourages the use of “modules”, which are self-contained applications within your site. Zend Framework’s MVC层鼓励使用modules,它在你的网站中是自我包含的应用程序。 Modules typically have a number of resource types by default, and Zend Framework even recommends a standard directory layout for modules(http://framework.zend.com/manual/1.12/en/project-structure.filesystem.html). 模块默认通常有一系列的资源类型,所以Zend Framework 甚至建议为模块建立一个标准的目录布局。Resource autoloaders are therefore quite useful in this paradigm — so useful that they are enabled by default when you create a bootstrap class for your module that extends Zend_Application_Module_Bootstrap. For more information, read the Zend_Loader_Autoloader_Module documentation. (说使用这个标准的好处)

永久链接:http://blog.ifeeline.com/188.html