问题
所以我尝试将我的应用程序分离到多个模块项目(每个都有自己的 composer.json ),然后真正的应用程序将通过composer加载所有这个项目
每个模块项目都有一个可通过浏览器访问的用户界面,可以单独启动,因此它不仅仅是一个简单的库。该文件将存在于每个模块项目中:
示例模块(依赖是我在application.config.php中的模块数组中编写的):
现在在我的最终应用程序中,让我们说 MyApplication 它需要 CMSModule 和 AccountingModule ,但我不能只在应用程序中编写这两个模块.config.php。相反,我必须写:
我只需要在 MyApplication
中写这两个这可以吗?我认为这个人想要在Loading Modules Dynamically in Zend Framework 2
中实现什么答案 0 :(得分:2)
根据我们在评论和问题中的交流,您将需要至少3个申请。我将给你一个简单的例子,你必须自己更新你对每个应用程序的要求。在composer.json配置之后,我将为您提供一个用作主题模块的骨架模块。
这些配置将用作root
composer.json配置文件。每个必需的包都应该有自己的作曲家文件列出特定包的要求。
例如,“核心”模块需要各种Zend Framework包。 “主题”包可能需要其他ZF包,例如zendframework/zend-view
,以便能够具有GUI布局。
composer.json
{
"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"
},
]
}
申请2的 composer.json
{
"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"
},
]
}
申请3的 composer.json
(没有主题)
{
"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 Framework的包的创建对于您创建的每个包几乎都是相同的,因此请根据您对每个模块(在包中)的要求进行修改。
此模块基本上替换了安装Zend Framework(2或3)Skeleton Application时默认获得的Application
模块。
我最近将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
属性中所定义的那样。
文件夹/文件结构为:
这些非常简单,因为Controller几乎是Skeleton Application提供的原始IndexController
的克隆。此实例中的Factory仅执行返回Controller的操作。因此,您可以使用FQCN将其配置替换为Zend Framework 3的InvokableFactory
,而不是生成Factory类。但是,如果您的ThemeController
需要一些要求(例如RegisterForm
),那么您将需要工厂提供这些要求。
<强> ThemeController 强>
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();
}
}
显然,您的模块不会有相同的要求。每个模块确保你弄清楚它们是什么。
对于我自己的主题模块,我在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(真正任何类型)文件混合到一个确定的位置。我建议你看看它(here)。
COMPANY_NAME
替换为您的Github帐户的用户名(或使用Bitbucket或Gitlab时的识别帐户名称)THEME_MODULE_NAME
替换为存储库名称"rwoverdijk/assetmanager": "^1.6"
)。版本锁定可以为您节省很多麻烦...... 此外:使用包作为“主题模块”,您可以完全删除Zend Framework的Skeleton应用程序最初附带的module/
文件夹。但是,建议您将module/
文件夹用于特定于应用程序的模块。如果你为所有东西创建一个包,你很快就会发现自己很难维护。
答案 1 :(得分:0)
你的布局是我最后的结果
但是,建议您将模块/文件夹用于特定于应用程序的模块。
有点,我最终放入每个特定包装的文件夹(zf2样式)
感谢您的澄清和回答。