gpt4 book ai didi

php - 在 Zend Framework 2 中动态加载模块

转载 作者:可可西里 更新时间:2023-11-01 01:13:50 26 4
gpt4 key购买 nike

我昨天也问过这个问题,但是这个问题包含代码。

问题

我的应用程序有多个模块和 2 种类型的用户帐户,一些模块总是加载,它们存在于 application.config.php 中,其中一些是 有条件的,即一些是为用户 type A 加载的,一些是为用户 type B

加载的

在阅读了有关 Stack Overflow 的文档和问题之后,我了解了 ModuleManager 的一些功能并开始实现我认为可能有效的逻辑。

一些我如何想出一种方法来加载 application.config.php 中不存在的模块 [SUCCESS] 但它们的配置不起作用 [问题] 即,如果在 onBootstrap 方法中我得到 ModuleManager 服务并执行 getLoadedModules() 我得到所有列表模块正确加载。之后,如果我尝试从那个动态加载的模块中获取一些服务,它会抛出异常。

Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for jobs_mapper

请注意,工厂和所有其他东西都非常好,因为如果我从 application.config.php 加载模块,它工作正常

同样,当我尝试从动态加载的模块访问任何路由时,它会抛出 404 Not Found,这清楚地表明这些模块的 module.config.php 中的配置没有加载,即使模块由 ModuleManager 加载。

代码

在我的应用程序模块的 Module.php 中,我实现了 InitProviderInterface 并添加了一个方法 init(ModuleManager $moduleManager) ,我在其中捕获了 moduleManager loadModules.post 事件触发器并加载模块

public function init(\Zend\ModuleManager\ModuleManagerInterface $moduleManager)
{
$eventManager = $moduleManager->getEventManager();
$eventManager->attach(\Zend\ModuleManager\ModuleEvent::EVENT_LOAD_MODULES_POST, [$this, 'onLoadModulesPost']);
}

然后在同一个类中,我调用方法 onLoadModulesPost 并开始加载我的动态模块

public function onLoadModulesPost(\Zend\ModuleManager\ModuleEvent $event)
{

/* @var $serviceManager \Zend\ServiceManager\ServiceManager */
$serviceManager = $event->getParam('ServiceManager');
$configListener = $event->getConfigListener();

$authentication = $serviceManager->get('zfcuser_auth_service');

if ($authentication->getIdentity())
{
$moduleManager = $event->getTarget();

...
...

$loadedModules = $moduleManager->getModules();
$configListener = $event->getConfigListener();
$configuration = $configListener->getMergedConfig(false);

$modules = $modulesMapper->findAll(['is_agency' => 1, 'is_active' => 1]);

foreach ($modules as $module)
{
if (!array_key_exists($module['module_name'], $loadedModules))
{
$loadedModule = $moduleManager->loadModule($module['module_name']);

//Add modules to the modules array from ModuleManager.php
$loadedModules[] = $module['module_name'];

//Get the loaded module
$module = $moduleManager->getModule($module['module_name']);

//If module is loaded succesfully, merge the configs
if (($loadedModule instanceof ConfigProviderInterface) || (is_callable([$loadedModule, 'getConfig'])))
{
$moduleConfig = $module->getConfig();
$configuration = ArrayUtils::merge($configuration, $moduleConfig);
}
}
}

$moduleManager->setModules($loadedModules);
$configListener->setMergedConfig($configuration);
$event->setConfigListener($configListener);
}
}

问题

  • 是否有可能实现我正在尝试的目标?
  • 如果是这样,最好的方法是什么?
  • 我的代码中缺少什么?

最佳答案

我认为您在这里尝试做的事情存在一些根本性错误:您正在尝试基于合并配置加载模块,因此在模块和合并配置之间创建循环依赖。

我不建议这样做。

相反,如果您有定义要加载应用程序的哪一部分的逻辑,请将其放在 config/application.config.php 中,它负责检索模块列表。

虽然在这个阶段,依赖任何服务还为时过早,因为服务定义也依赖于合并的配置。

另一件需要澄清的事情是,您正在尝试根据经过身份验证的用户(请求信息,而不是环境信息)是否符合特定条件来做出这些决定,然后修改整个应用程序基于

不要那样做:相反,通过在它前面放置一个守卫,将决定移动到要有条件地启用/禁用的组件中。

关于php - 在 Zend Framework 2 中动态加载模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45295059/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com