代码之家  ›  专栏  ›  技术社区  ›  Sohel Ahmed Mesaniya

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

  •  1
  • Sohel Ahmed Mesaniya  · 技术社区  · 6 年前

    我有一个模块层次结构如下

    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

    DefaultController 属于 Grapemod 模块我需要知道它的所有父模块。怎么用?

    现在在 默认控制器 属于 Lemonmod 模块我需要知道它的所有子模块。怎么用?

    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
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   rob006    6 年前

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

    $modules = $controller->getModules();
    

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

    阵列中的第一个模块是最外层的模块(即 最后一个是最里面的一个。

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


    Module::getModules() . 但是,对于未加载的模块,它将返回module config而不是module instance—这在中有说明 $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);