在 Yii2 中获取子模块的所有父模块列表,反之亦然
Get list of all parent modules of a child module and vice versa in Yii2
我的模块层次结构如下
yii/web/Application
->
frontend\modules\mangomod\MangomodModule
-> frontend\modules\mangomod\modules\lemonmod\Lemonmod
-> frontend\modules\mangomod\modules\lemonmod\modules\grapemod\Grapemod
自举模块是:
yii\debug\Module
和 yii\gii\Module
现在在 Grapemod
模块的 DefaultController
中,我需要知道它的所有父模块。怎么样?
和
现在在 Lemonmod
模块的 DefaultController
中,我需要知道它的所有子模块。怎么样?
我试过 yii\base\Application::$loadedModules
但它也提供了我不想要的自举模块,例如 gii
和 debug
。
这是 yii\base\Application::$loadedModules
的结果:
[0] => yii\web\Application
[1] => frontend\modules\mangomod\MangomodModule
[2] => yii\debug\Module
[3] => yii\gii\Module
[4] => frontend\modules\mangomod\modules\lemonmod\Lemonmod
[5] => frontend\modules\mangomod\modules\lemonmod\modules\grapemod\Grapemod
更新
lemonmod 获得了它的兄弟模块
frontend\modules\mangomod\modules\lemonmod2\Lemonmod2Module
grapemod 获得了它的兄弟模块
frontend\modules\mangomod\modules\lemonmod\modules\grapemod2\Grapemod2Module
要获取控制器的所有祖先模块,您可以使用 Controller::getModules()
方法:
$modules = $controller->getModules();
Returns all ancestor modules of this controller.
The first module in the array is the outermost one (i.e., the
application instance), while the last is the innermost one.
https://www.yiiframework.com/doc/api/2.0/yii-base-controller#getModules()-detail
要获取子模块列表,您可以使用此方法的 Module::getModules()
. However it will return module config instead of module instance for not loaded modules - it is documented in $loadedOnly
参数:
Whether to return the loaded sub-modules only. If this is set false
, then all sub-modules registered in this module will be returned, whether they are loaded or not. Loaded modules will be returned as objects, while unloaded modules as configuration arrays.
如果你想获取所有模块的实例,你应该手动实例化非加载模块:
$modules = [];
foreach ($module->getModules() as $id => $child) {
if (!$child instanceof Module) {
$child = $module->getModule($id);
}
$modules[] = $child;
}
此外,这将 return 仅引导子模块 - 要获取所有后代,您需要遍历模块树:
/**
* Return all descendants of given module.
*
* @param Module $module
* @return Module[]
*/
$traverse = function (Module $module) use (&$traverse) {
$modules = [];
foreach ($module->getModules() as $id => $child) {
if (!$child instanceof Module) {
$child = $module->getModule($id);
}
$modules[] = $child;
$modules = array_merge($modules, $traverse($child));
}
return $modules;
};
$modules = $traverse($module);
我的模块层次结构如下
yii/web/Application
->
frontend\modules\mangomod\MangomodModule
-> frontend\modules\mangomod\modules\lemonmod\Lemonmod
-> frontend\modules\mangomod\modules\lemonmod\modules\grapemod\Grapemod
自举模块是:
yii\debug\Module
和 yii\gii\Module
现在在 Grapemod
模块的 DefaultController
中,我需要知道它的所有父模块。怎么样?
和
现在在 Lemonmod
模块的 DefaultController
中,我需要知道它的所有子模块。怎么样?
我试过 yii\base\Application::$loadedModules
但它也提供了我不想要的自举模块,例如 gii
和 debug
。
这是 yii\base\Application::$loadedModules
的结果:
[0] => yii\web\Application
[1] => frontend\modules\mangomod\MangomodModule
[2] => yii\debug\Module
[3] => yii\gii\Module
[4] => frontend\modules\mangomod\modules\lemonmod\Lemonmod
[5] => frontend\modules\mangomod\modules\lemonmod\modules\grapemod\Grapemod
更新 lemonmod 获得了它的兄弟模块
frontend\modules\mangomod\modules\lemonmod2\Lemonmod2Module
grapemod 获得了它的兄弟模块
frontend\modules\mangomod\modules\lemonmod\modules\grapemod2\Grapemod2Module
要获取控制器的所有祖先模块,您可以使用 Controller::getModules()
方法:
$modules = $controller->getModules();
Returns all ancestor modules of this controller.
The first module in the array is the outermost one (i.e., the application instance), while the last is the innermost one.
https://www.yiiframework.com/doc/api/2.0/yii-base-controller#getModules()-detail
要获取子模块列表,您可以使用此方法的 Module::getModules()
. However it will return module config instead of module instance for not loaded modules - it is documented in $loadedOnly
参数:
Whether to return the loaded sub-modules only. If this is set
false
, then all sub-modules registered in this module will be returned, whether they are loaded or not. Loaded modules will be returned as objects, while unloaded modules as configuration arrays.
如果你想获取所有模块的实例,你应该手动实例化非加载模块:
$modules = [];
foreach ($module->getModules() as $id => $child) {
if (!$child instanceof Module) {
$child = $module->getModule($id);
}
$modules[] = $child;
}
此外,这将 return 仅引导子模块 - 要获取所有后代,您需要遍历模块树:
/**
* Return all descendants of given module.
*
* @param Module $module
* @return Module[]
*/
$traverse = function (Module $module) use (&$traverse) {
$modules = [];
foreach ($module->getModules() as $id => $child) {
if (!$child instanceof Module) {
$child = $module->getModule($id);
}
$modules[] = $child;
$modules = array_merge($modules, $traverse($child));
}
return $modules;
};
$modules = $traverse($module);