Zend框架模块库

时间:2012-11-14 11:30:10

标签: php zend-framework refactoring autoload

我正在开发一个Zend Framework(1.11)应用程序,我将其移植到模块中,以便开发人员可以插入和播放我们软件的各种附加功能,并轻松删除。

我遇到的问题(似乎无法找到答案)我有可靠的库代码,即我的结构目前是

- application
  - (the standard ZF stuff)
  - modules
     - testModule
        - Bootstrap.php
        - controllers
        - configs
        - views
 - library
    - CoreStuff
       - Class.php
       - SpecialClass.php
    - testModuleLibrary
       - Class.php
       - SpecialClass.php

我真正想要的是这样,其他开发人员更容易将模块安装到我们的系统中。

 - application
   - (the standard ZF stuff)
   - modules
      - testModule
         - Bootstrap.php
         - controllers
         - configs
         - views
         - library
            - Class.php
            - SpecialClass.php
 - library
    - CoreStuff
       - Class.php
       - SpecialClass.php

我可以在Bootstrap模块中使用Autoloader吗?或者我是否必须将其添加到我的包含路径?

[编辑]

这是我当前的模块引导程序,我已经一次又一次地看到这段代码与我危险的谷歌搜索,但它似乎没有任何区别

<?php

    class Notifications_Bootstrap extends Zend_Application_Module_Bootstrap {

        protected function _initLibraryAutoloader () {
            return $this->getResourceLoader()->addResourceType('library', 'library', 'library');
        }

}

4 个答案:

答案 0 :(得分:1)

我已使用以下代码解决了我的问题。我完全不知道为什么我之前没有想出这个:( :(

class Notifications_Bootstrap extends Zend_Application_Module_Bootstrap {
    protected function _initConfig () {
        set_include_path(implode(PATH_SEPARATOR, array(
            dirname(__FILE__) . '/library',
            get_include_path(),
        )));
    }
}

答案 1 :(得分:1)

您可以在应用程序配置文件中定义库路径,如: 这是YML中的示例

project:
    bootstrap:
        path: APPLICATION_PATH/Bootstrap/index.php
        class: Bootstrap_Index
    Autoloadernamespaces:
        - Zend_
        - Library1_
        - Library2_
    resources:
        FrontController:
            moduledirectory:
                - APPLICATION_PATH/modules
......

这是INI格式的例子

[bootstrap]
        Autoloadernamespaces[] = "Zend_"
        Autoloadernamespaces[] = "Library1_"
        Autoloadernamespaces[] = "Library2_"

        resources.FrontController.moduleDirectory = APPLICATION_PATH"/modules"
        resources.FrontController.resetRouterOnEveryRequest = true

        bootstrap.path = APPLICATION_PATH "/Bootstrap/index.php"
        bootstrap.class = "Bootstrap_Index"

关于项目目录结构,我建议你使用类似的东西:

- application 
    - Bootstrap
        - index.php
    - Modules
        - Mod1
            - controllers
            - views
        - Mod2
            - controllers
            - views
        ...
- library 
    - Zend
        - ...
    - Library1
        - ...
    - Library2
        - ...

完成目录结构后,您可以使用/:module /:controller /:action等URL,并将所有第三方代码分别保存在自己的池库目录中

答案 2 :(得分:0)

您可以使用模块的Boostrap.php。 提供功能

protected function _initAutoload(){}

使lib可用。因此,你可以让模块开发人员去做,因为它是开发模块以使其资源可加载的工作的一部分:)

答案 3 :(得分:0)

我正在添加此回复,希望能够回答原始查询,并对此处提交的一些项目进行一些说明。我是ZF 1.11中模块的积极开发人员,并且在我们维护的几个模块之一中使用我每天要解释的内容。

我对这个回复的长度提前道歉。有几个项目需要考虑和考虑。

首先,为了实施。

据我所知,以下提供的代码片段为1.8,并且不会是1.11所需的。

<?php

class Notifications_Bootstrap extends Zend_Application_Module_Bootstrap {

    protected function _initLibraryAutoloader () {
        return $this->getResourceLoader()->addResourceType('library', 'library', 'library');
    }

}

以下虽然可以正常工作,但我会在下面解释几个关键要素。

protected function _initLibraryAutoloader () {
    return $this->getResourceLoader()->addResourceType('library', 'library', 'Library_');
}

您会注意到第三个参数(命名空间)略有不同。对此的最佳解释是可能将函数更新为以下内容:

protected function _initLibraryAutoloader () {
    $this->getResourceLoader()->addResourceType('library', 'library', 'Library_');
    var_dump($this->getResourceLoader()->getResourceTypes());die;
}

您的输出应类似于:

Array
(
[dbtable] => Array
    (
        [namespace] => Admin_Model_DbTable
        [path] => /path/to/trunk/application/modules/admin/models/DbTable
    )

[mappers] => Array
    (
        [namespace] => Admin_Model_Mapper
        [path] => /path/to/trunk/application/modules/admin/models/mappers
    )

[form] => Array
    (
        [namespace] => Admin_Form
        [path] => /path/to/trunk/application/modules/admin/forms
    )

[model] => Array
    (
        [namespace] => Admin_Model
        [path] => /path/to/trunk/application/modules/admin/models
    )

[plugin] => Array
    (
        [namespace] => Admin_Plugin
        [path] => /path/to/trunk/application/modules/admin/plugins
    )

[service] => Array
    (
        [namespace] => Admin_Service
        [path] => /path/to/trunk/application/modules/admin/services
    )

[viewhelper] => Array
    (
        [namespace] => Admin_View_Helper
        [path] => /path/to/trunk/application/modules/admin/views/helpers
    )

[viewfilter] => Array
    (
        [namespace] => Admin_View_Filter
        [path] => /path/to/trunk/application/modules/admin/views/filters
    )

[library] => Array
    (
        [namespace] => Admin_Library
        [path] => /path/to/trunk/application/modules/admin/library
    )

)

如果您将此与之前的“库”作为第三个参数进行比较,您会在一秒钟内看到它为何会产生如此重要的差异。

重申一下,此时,您已声明一个前缀为“Library_”的库类型,该类型将转换为“Admin_Library”。现在,要实现这一点,您将在模块中拥有库文件夹,就像在主应用程序模块中一样,只需稍作调整即可。要具有Admin模块特定的控制器操作(Admin_Library_Controller_Action),您将拥有库/ Controller / Action.php,其类名为Admin_Library_Controller_Action。这是大多数人最初感到困惑的事情,但它与您应该在模块中使用的其他资源名称空间非常相似。

结论技术解释。如果您不再阅读,您将能够拥有一个特定于您的模块的库,并且完全独立,以便轻松复制/粘贴可重用模块。

现在就我在这里看到的其他一些回复发表一些评论。

无限注意

  

“如果您遵循您的结构,您最终可能会使用 - Module1(Lib1,Lib2) - Module2(Lib1,Lib3),因此您将开始复制所需的库。”

这在技术上是正确的,但如果您发现自己经常在整个地方使用相同的库,那么实际开发风格中会出现更多问题。我们通常将这些常用项存储在另一个库中,我们将它们用作外部,与Zend相同,并且放在主应用程序库文件夹中的Zend旁边。

如果您已经这样做了,我认为可能需要进一步澄清的是,如果您正确使用名称空间,您绝对不必担心库类名称的冲突。你可能会在很短的时间内发现你需要在多个模块中使用相同代码的类,但是一旦发生这种情况,你应该考虑除了上面提到的Zend之外的公共库。

我再次对此回复的长度道歉。我希望它可以帮助任何可能遇到这篇文章的人需要在模块中实现库。