Загрузка модулей с несколькими модулями в Zend Framework 2

Проблемы

Поэтому я пытаюсь отделить свое приложение от проекта с несколькими модулями (у каждого есть свой composer.json), тогда реальное приложение загрузит весь этот проект через композитор.

Каждый проект этого модуля будет иметь пользовательский интерфейс, доступный через браузер, и может запускаться индивидуально, так что это не просто библиотека. Этот файл будет существовать в каждом проекте модуля:

  • конфиг/application.config.php
  • общедоступный/index.php

Пример модуля (зависимость — это то, что я пишу в массиве модулей в application.config.php):

  • UIModule
    • Dependency : AssetManager, UIModule
  • CMSModule
    • Dependency : UIModule, CMSModule
  • AccountingModule:
    • Dependency : UIModule, AccountingModule

Теперь в моем последнем приложении скажем MyApplication, ему нужны как CMSModule, так и AccountingModule, но я не могу написать только эти два модуля в application.config. php. Вместо этого я должен написать:

  • AssetManager -> это должно быть загружено UIModule
  • UIModule -> это должно быть загружено CMS/модулем учета
  • CMSModule
  • Модуль учета

Мне нужно только написать эти два в MyApplication

  • CMSModule
  • Модуль учета

Это можно сделать? чего я думаю, что этот парень хочет достичь в Динамическая загрузка модулей в Zend Framework 2< /а>

Примерно так я добавляю еще один дополнительный модуль. модуль развязки


person Wiryono Lauw    schedule 13.03.2018    source источник
comment
Вы ссылаетесь на вопрос, читали ли вы этот ответ на этот вопрос? Вы пытаетесь использовать конфигурацию (все конфигурации объединены в 1 массив) для 1 приложения, как если бы это было более 1 приложения. Мой совет, основанный на вашем вопросе: создайте 4 приложения с перекрывающимися зависимостями (например, модуль пользовательского интерфейса и модуль аутентификации).   -  person rkeet    schedule 13.03.2018
comment
это больше похоже на рекурсивное включение модуля, такого как композитор. Но, может быть, лучше проверить, не включен ли модуль, а затем бросить какое-то исключение   -  person Wiryono Lauw    schedule 13.03.2018
comment
Мой совет для вас, чтобы построить более 1 приложения стоит. Ваш комментарий действительно звучит так, будто вам нужно 3 (?) Приложения, но вы не можете создавать более 1 приложения. Если у вас есть приложения 1, 2 и 3, что мешает вам использовать все 3 модуля A, B и C. Тогда пусть приложение 2 также использует модуль D, а приложение 3 использует модуль E. На самом деле более удобно совместно использовать модули поставщика между приложениями, чем совместно использовать приложения между модулями.   -  person rkeet    schedule 13.03.2018
comment
да, это то, чего я хочу добиться, каждый модуль будет разделен для каждого поставщика, поэтому я могу разделить его на разных разработчиков, и они не будут легко ломать другой пакет при изменении. Но если модуль должен иметь пользовательский интерфейс (представление), такой как форма и другой дизайн, а не только сервисную библиотеку, тогда нужно написать приложение для каждого модуля. Затем пришла идея: давайте иметь один глобальный модуль приложения, который будет использоваться другим модулем в качестве представления, чтобы макет всегда был одинаковым.   -  person Wiryono Lauw    schedule 15.03.2018


Ответы (2)


Судя по нашему обмену комментариями и вопросу, вам понадобится как минимум 3 приложения. Я приведу вам краткие примеры, вам придется обновлять свои требования для каждого приложения самостоятельно. После конфигов composer.json я дам вам каркасный модуль для использования в качестве модуля темы.

Эти конфигурации должны использоваться в качестве файлов конфигурации root composer.json. Каждый из требуемых пакетов должен иметь свои собственные требования к листингу файлов композитора для конкретного пакета.

Например, для «основного» модуля потребуются различные пакеты Zend Framework. Для пакета «тема» могут потребоваться другие пакеты ZF, такие как zendframework/zend-view, чтобы иметь возможность иметь макет графического интерфейса.


Настройка 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": "[email protected]/COMPANY_NAME/MODULE_1_THEME.git"
    },
    {
      "type": "git",
      "url": "[email protected]/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": "[email protected]/COMPANY_NAME/MODULE_1_THEME.git"
    },
    {
      "type": "git",
      "url": "[email protected]/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": "[email protected]/COMPANY_NAME/MODULE_4_AUTH_MODULE.git"
    }
  ]
}

Как видите, приложения 1 и 2 используют один и тот же пакет MODULE_THEME, как вы указали на диаграмме в своем вопросе.

Теперь создание пакета для Zend Framework почти одинаково для каждого создаваемого вами пакета, поэтому измените то, что следует ниже, в соответствии с требованиями, которые у вас есть для каждого модуля (в пакете).

Создание модуля темы

Этот модуль в основном заменяет модуль Application, который вы получаете по умолчанию при установке приложения Zend Framework (2 или 3).

Недавно я обновил все, что у меня есть с Zend Framework, до Zend Framework 3, поэтому я дам вам настройку, адаптированную для ZF3. Тем не менее, переход на ZF2 не должен быть слишком большой проблемой.

Создайте конфиг для того, что вам нужно

Типичная тема требует нескольких вещей, таких как:

  • темы/макеты для разных типов страниц (например, логин, обычная тема, ошибки)
  • переводы
  • отображение ошибок (в режиме разработки)
  • маршрут по умолчанию "домашний"
  • контроллер для обработки «домашнего» маршрута по умолчанию

Конфиг для этого может быть (не ограничиваясь! Делайте с ним что хотите!) как таковой в module.config.php модуля Theme

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/
      • module.config.php
    • src/
      • Controller/
        • ThemeController.php
      • Factory/
        • ThemeControllerFactory.php
      • Модуль.php
    • view/
      • error/
        • index.phtml
        • 404.phtml
      • layout/
        • index.phtml
        • логин.phtml
        • регистрация.phtml
    • композитор.json

ThemeController и *Фабрика

Это очень просто, так как Контроллер в значительной степени является клоном оригинального IndexController, предоставляемого приложением Skeleton. Фабрика в этом случае ничего не делает, кроме как возвращает Контроллер. Таким образом, вы можете заменить его конфигурацию на FQCN на InvokableFactory Zend Framework 3 и не создавать класс Factory. Однако, если вашему ThemeController нужны какие-то требования (например, RegisterForm), вам понадобится Фабрика, чтобы предоставить их.

Контроллер темы

namespace COMPANY_NAME\Controller;

use Zend\Mvc\Controller\AbstractActionController;

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

ThemeControllerFactory

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();
    }
}

Требования к композитору темы

Очевидно, что ваши модули не будут иметь одинаковых требований. Убедитесь, что вы выяснили, что они из себя представляют, для каждого модуля.

Для моего собственного модуля Theme у меня есть следующие требования Zend Framework в моем файле composer.json:

{
    "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/, изначально поставляемую с приложением Skeleton Zend Framework. Тем не менее, вам рекомендуется использовать папку module/ для конкретных модулей приложения. Если вы создадите пакет для всего, вы скоро окажетесь в аду обслуживания.

person rkeet    schedule 16.03.2018
comment
Если/когда это возможно, используйте явные версии для необходимых пакетов (например, rwoverdijk/assetmanager: ^1.6). Блокировка версии может избавить вас от многих хлопот в будущем ... Работает ли это с zf3, я пробовал 1.7.3, это не работает, выдает какое-то исключение. Вот почему я пока возвращаюсь к zf2 - person Wiryono Lauw; 18.03.2018
comment
Да, блокировка версий работает всегда. В случае, если вы находитесь в разработке, вы можете использовать "*" в качестве версии (неограниченная версия), чтобы вы получали самые последние обновления. Затем, очевидно, прежде чем запускать его в производство, вы сравниваете свой composer.lock файл и добавляете версии установленных пакетов поставщиков в свои composer.json файлы. Таким образом, к моменту начала производства у вас будет все в актуальном состоянии. Однако в случае крупных обновлений это может привести к задержке разработки, когда поставщик поставляет такое крупное обновление ;) Так что всегда будьте осторожны. - person rkeet; 18.03.2018

Да, ваш макет - это то, к чему я пришел в конце

Тем не менее, вам рекомендуется использовать модуль/папку для конкретных модулей приложения.

В конце концов, я помещаю в папку для каждого конкретного пакета (стиль zf2)

  • PACKAGE FOLDER
    • composer.json
    • Module.php (это для модульного теста php)
    • public (for UI Package I have this)
      • index.php
    • config
      • application.config.php (apparently need to write each version for each package)
    • тесты
    • src
      • MODULE_NAME
        • asset
        • src
          • MODULE_NAME
            • Controller
            • Оказание услуг
            • Модель
            • { Другой ... }
        • конфигурация
        • Посмотреть
        • Модуль.php

Спасибо за ваше разъяснение и ответ.

person Wiryono Lauw    schedule 17.03.2018