1

问题

所以我尝试将我的应用程序解耦到多个模块项目(每个都有自己的composer.json),然后真正的应用程序将通过 composer 加载所有这个项目

每个模块项目都有一个可通过浏览器访问的用户界面,并且可以单独启动,因此它不仅仅是一个简单的库。该文件将存在于每个模块项目中:

  • 配置/应用程序.config.php
  • 公共/index.php

示例模块(依赖是我在 application.config.php 的模块数组中写的):

  • UI模块
    • 依赖:AssetManager、UIModule
  • CMS模块
    • 依赖:UIModule、CMSModule
  • 会计模块:
    • 依赖:UIModule、AccountingModule

现在在我的最终应用程序中假设MyApplication它需要CMSModuleAccountingModule,但我不能只在 application.config.php 中编写这两个模块。相反,我必须写:

  • AssetManager -> 这应该由 UIModule 加载
  • UIModule -> 这应该由 CMS/会计模块加载
  • CMS模块
  • 会计模块

我只需要在MyApplication中写这两个

  • CMS模块
  • 会计模块

这是可以做到的吗?我认为这家伙想在 Zend Framework 2 中动态加载模块中实现什么

像这样,我添加了另一个附加模块。 解耦模块

4

2 回答 2

2

根据我们在评论和问题中的交流,您将需要至少 3 个应用程序。我会给你一个简单的例子,你必须自己更新每个应用程序的要求。在 composer.json 配置之后,我会给你一个骨架模块用作主题模块。

这些配置将用作rootcomposer.json 配置文件。每个必需的包都应该有自己的特定包的作曲家文件列表要求。

例如,一个“核心”模块需要各种 Zend Framework 包。“主题”包可能需要其他 ZF 包,例如zendframework/zend-view为了能够具有 GUI 布局。


设置 3 个具有重叠需求的独立 Zend Framework 应用程序

composer.json申请 1

{
  "name": "COMPANY_NAME/APPLICATION_1",
  "require": {
    "COMPANY_NAME/MODULE_1_THEME": "*",
    "COMPANY_NAME/MODULE_2_CMS": "*"
  },
  "repositories": [
    {
      "type": "git",
      "url": "git@github.com/COMPANY_NAME/MODULE_1_THEME.git"
    },
    {
      "type": "git",
      "url": "git@github.com/COMPANY_NAME/MODULE_2_CMS.git"
    },
  ]
}

composer.json申请 2

{
  "name": "COMPANY_NAME/APPLICATION_2",
  "require": {
    "COMPANY_NAME/MODULE_1_THEME": "*",
    "COMPANY_NAME/MODULE_3_ACCOUNTING": "*"
  },
  "repositories": [
    {
      "type": "git",
      "url": "git@github.com/COMPANY_NAME/MODULE_1_THEME.git"
    },
    {
      "type": "git",
      "url": "git@github.com/COMPANY_NAME/MODULE_3_ACCOUNTING.git"
    },
  ]
}

composer.json适用于应用程序 3(没有主题)

{
  "name": "COMPANY_NAME/APPLICATION_3",
  "require": {
    "COMPANY_NAME/MODULE_4_AUTH_MODULE": "*"
  },
  "repositories": [
    {
      "type": "git",
      "url": "git@github.com/COMPANY_NAME/MODULE_4_AUTH_MODULE.git"
    }
  ]
}

如您所见,应用程序 1 和 2 使用相同的MODULE_THEME包,正如您在问题图表中概述的那样。

现在,为 Zend 框架创建的包对于您创建的每个包几乎都是相同的,因此请根据您对每个模块(在包中)的要求修改以下内容。

创建主题模块

该模块基本上替换了Application您在安装 Zend Framework(2 或 3)骨架应用程序时默认获得的模块。

我最近将 Zend Framework 的所有内容都升级到了 Zend Framework 3,因此我将为您提供为 ZF3 量身定制的设置。但是,降级 ZF2 应该不是什么大问题。

根据您的需要创建配置

一个典型的主题需要一些东西,例如:

  • 不同类型页面的主题/布局(例如登录、正常主题、错误)
  • 翻译
  • 显示错误(在开发模式下)
  • 默认“家”路线
  • 控制器处理默认的“家”路由

对此的配置可以是(不限于!随心所欲!)在module.config.php主题模块中

namespace COMPANY_NAME\Theme;

use COMPANY_NAME\Theme\Controller\ThemeController;
use COMPANY_NAME\Theme\Factory\ThemeControllerFactory;

return [
    'controllers' => [
        'factories' => [
            ThemeController::class => ThemeControllerFactory::class,
        ],
    ],
    'router' => [
        'routes' => [
            'home' => [
                'type' => Literal::class,
                'may_terminate' => true,
                'options' => [
                    'route'    => '/',
                    'defaults' => [
                        'controller' => ThemeController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
        ],
    ],
    'route_layouts' => [
        '*'         => 'layout/layout',
        'login'     => 'layout/login',
        'register'  => 'layout/login',
        'error*'    => 'error/index',
        'error/404' => 'error/404',
    ],
    'translator' => [
        'locale' => 'en_US',
        'translation_file_patterns' => [
            [
                'type'     => 'gettext',
                'base_dir' => __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'language',
                'pattern'  => '%s.mo',
            ],
        ],
    ],
    'view_manager' => [
        // controller_map is optional, but depending on your composer package nesting, could be a great help. Have a look here for how to use: https://blog.alejandrocelaya.com/2015/08/14/working-with-sub-namespaced-modules-in-zend-framework-2-the-right-way/
        'controller_map' => [
            'COMPANY_NAME\Theme' => 'company_name_path_alias',
        ],
        'display_not_found_reason' => true,
        'display_exceptions'       => true,
        'doctype'                  => 'HTML5',
        'not_found_template'       => 'error/404',
        'exception_template'       => 'error/index',
        'template_map' => [
            'layout/layout' => __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR .
                'layout' . DIRECTORY_SEPARATOR . 'layout.phtml',
            'layout/login' => __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR .
                'layout' . DIRECTORY_SEPARATOR . 'login.phtml',
            'error/404'               => __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR .
                'error' . DIRECTORY_SEPARATOR . '404.phtml',
            'error/index'             => __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR .
                'error' . DIRECTORY_SEPARATOR . 'index.phtml',
        ],
        'template_path_stack' => [
            __DIR__ . DIRECTORY_SEPARATOR .'..' . DIRECTORY_SEPARATOR . 'view',
        ],
    ],
];

基于配置的文件/模块结构

包的位置将是/vendor/COMPANY_NAME/THEME_MODULE_NAME(正如您在此包的文件中的name属性中定义的那样。composer.json

文件夹/文件结构将是:

  • /vendor/COMPANY_NAME/THEME_MODULE_NAME
    • 配置/
      • 模块.config.php
    • 源/
      • 控制器/
        • 主题控制器.php
      • 工厂/
        • ThemeControllerFactory.php
      • 模块.php
    • 看法/
      • 错误/
        • 索引.phtml
        • 404.phtml
      • 布局/
        • 索引.phtml
        • 登录.phtml
        • 注册.phtml
    • 作曲家.json

主题控制器和*工厂

这些非常简单,因为控制器几乎是IndexController骨架应用程序提供的原始控制器的克隆。在这种情况下,工厂除了返回控制器之外什么都不做。因此,您可以将其配置替换为InvokableFactoryZend Framework 3 的 FQCN,而不是创建 Factory 类。但是,如果您ThemeController需要一些要求(例如 a RegisterForm),您将需要 Factory 来提供这些。

主题控制器

namespace COMPANY_NAME\Controller;

use Zend\Mvc\Controller\AbstractActionController;

class ThemeController extends AbstractActionController
{
    public function indexAction()
    {
        return [];
    }
}

主题控制器工厂

namespace COMPANY_NAME\Factory;

use COMPANY_NAME\Controller\ThemeController;
use Zend\ServiceManager\Factory\FactoryInterface;

class ThemeControllerFactory implements FactoryInterface
{
    /**
     * @param ContainerInterface $container
     * @param string $requestedName
     * @param array|null $options
     * @return ThemeController
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        return new ThemeController();
    }
}

主题作曲家要求

显然,您的模块不会有相同的要求。确保你弄清楚它们是什么,每个模块。

对于我自己的主题模块,我的composer.json文件中有以下 Zend Framework 要求:

{
    "name": "COMPANY_NAME/THEME_MODULE_NAME",
    "require": {
        "zendframework/zend-di": "*",
        "zendframework/zend-navigation": "*",
        "zendframework/zend-view": "*",
    }
}

在该require部分中,我还有:"rwoverdijk/assetmanager": "^1.6",。该模块用于将文件的所有 CSS、JS(实际上是任何类型)混合到一个确定的位置。我建议你看看它(在这里)。


答案注释

  • 替换COMPANY_NAME为您的 Github 帐户的用户名(如果您使用的是 Bitbucket 或 Gitlab,则替换为识别帐户名称)
  • 替换THEME_MODULE_NAME为存储库的名称
  • 如果/可能的话,为所需的包使用显式版本(例如"rwoverdijk/assetmanager": "^1.6")。版本锁定可以为你省去很多以后的麻烦...

另外:使用包作为“主题模块”允许您完全删除module/最初随 Zend Framework 的 Skeleton Application 提供的文件夹。但是,特此建议您将该module/文件夹用于特定于应用程序的模块。如果你为所有东西创建一个包,你很快就会发现自己是维护地狱。

于 2018-03-16T13:20:50.117 回答
0

是的,你的布局是我最后来的

但是,特此建议您将 module/ 文件夹用于特定于应用程序的模块。

有点,我最终将每个特定包( zf2 样式)放在一个文件夹中

  • 包文件夹
    • 作曲家.json
    • Module.php (用于 php 单元测试)
    • 公共(对于 UI 包我有这个)
      • 索引.php
    • 配置
      • application.config.php (显然需要为每个包编写每个版本)
    • 测试
    • 源代码
      • MODULE_NAME
        • 资产
        • 源代码
          • MODULE_NAME
            • 控制器
            • 服务
            • 模型
            • { 其他 ... }
        • 配置
        • 看法
        • 模块.php

感谢您的澄清和回答。

于 2018-03-17T22:50:47.663 回答