获取Yii2中子模块的所有父模块的列表,反之亦然

时间:2018-09-08 14:50:58

标签: php yii module yii2

我的模块层次结构如下

yii/web/Application-> frontend\modules\mangomod\MangomodModule-> frontend\modules\mangomod\modules\lemonmod\Lemonmod-> frontend\modules\mangomod\modules\lemonmod\modules\grapemod\Grapemod

引导程序模块是:

yii\debug\Moduleyii\gii\Module

现在在DefaultController模块的Grapemod中,我需要了解其所有父模块。怎么样?

现在在DefaultController模块的Lemonmod中,我需要知道其所有子模块。怎么样?

我尝试过yii\base\Application::$loadedModules,但它也提供了我不想在列表中使用的自举模块,例如giidebug

这是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

1 个答案:

答案 0 :(得分:1)

要获取控制器的所有祖先模块,可以使用Controller::getModules()方法:

$modules = $controller->getModules();
  

返回此控制器的所有祖先模块。

     

数组中的第一个模块是最外层的模块(即   应用程序实例),而最后一个是最里面的。

     

https://www.yiiframework.com/doc/api/2.0/yii-base-controller#getModules()-detail


要获取子模块的列表,可以使用Module::getModules()。但是,对于未加载的模块,它将返回模块配置而不是模块实例-此方法的$loadedOnly参数中记录了该文件:

  

是否仅返回已加载的子模块。如果将其设置为false,则将返回在此模块中注册的所有子模块,无论是否已加载。 已加载的模块将作为对象返回,而已卸载的模块将作为配置数组

如果要获取所有模块的实例,则应手动实例化未加载的模块:

$modules = [];
foreach ($module->getModules() as $id => $child) {
    if (!$child instanceof Module) {
        $child = $module->getModule($id);
    }
    $modules[] = $child;
}

这还将仅返回直接子模块-要获得遍历模块树所需的所有后代:

/**
 * 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);