php 模块中的 Yii2 路由定义

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27954182/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 23:38:16  来源:igfitidea点击:

Yii2 routes definition in modules

phproutesyii2

提问by user1954544

Is there any solution to add routes from module configuration?

是否有任何解决方案可以从模块配置中添加路由?

Example. We have main config where we describe

例子。我们有我们描述的主要配置

'components' => [
    'urlManager' => [
                'enablePrettyUrl' => true,
                'showScriptName' => false,
                'rules' => require(FILE_PATH_CONFIG_ENV . '_routes.php') // return array
    ],
]

in each module we load custom config file with private parameters

在每个模块中,我们使用私有参数加载自定义配置文件

public function loadConfig($sFileName = 'main', $sFolderName = 'config')
{
    Yii::configure($this, require($this->getBasePath() . DS . $sFolderName . DS . $sFileName . '.php'));

    return $this;
}

Config file

配置文件

return [
    'components' => [
        'urlManager' => [
            'class' => 'yii\web\UrlManager',
            'rules' => [
                '/admin' => '/admin/index/index',
            ]
        ]
    ]
];

And now I need somehow merge current config (main for web application) with config loaded from module. In end I want describe in module config routes only for this module and use them for pretty urls (user friendly url). How can I do this one? This examples not working when I create url /admin/index/index, it shows me /admin/index/indexbut I want /adminas mentioned in module rules.

现在我需要以某种方式将当前配置(主要用于 Web 应用程序)与从模块加载的配置合并。最后,我只想在模块配置路由中描述这个模块,并将它们用于漂亮的 url(用户友好的 url)。我怎样才能做到这一点?这个例子在我创建 url 时不起作用/admin/index/index,它向我展示了我,/admin/index/index但我想要/admin模块规则中提到的。

采纳答案by arogachev

Separating url rules for modules is mentioned in official documentation here.

此处的官方文档中提到了模块的分隔 url 规则。

And I think this is more optimum approach unlike merging and declaring all rules in one config file.

而且我认为这是一种更优化的方法,与在一个配置文件中合并和声明所有规则不同。

The rules are parsed in order they are declared (this is mentioned here), so with the separation you can skip other modules urls. In case of large amount of rules it can give perfomance boost.

规则按照声明的顺序进行解析(这里提到这一点),因此通过分离,您可以跳过其他模块的 url。在大量规则的情况下,它可以提高性能。

回答by user1954544

So I did this way (this is full answer for a question).

所以我这样做了(这是一个问题的完整答案)。

Create Bootstrap class special for module.

为模块创建专用的 Bootstrap 类。

namespace app\extensions;

use yii\base\BootstrapInterface;

/**
 * Class ModuleBootstrap
 *
 * @package app\extensions
 */
class ModuleBootstrap implements BootstrapInterface
{
    /**
     * @param \yii\base\Application $oApplication
     */
    public function bootstrap($oApplication)
    {
        $aModuleList = $oApplication->getModules();

        foreach ($aModuleList as $sKey => $aModule) {
            if (is_array($aModule) && strpos($aModule['class'], 'app\modules') === 0) {
                $sFilePathConfig = FILE_PATH_ROOT . DS . 'modules' . DS . $sKey . DS . 'config' . DS . '_routes.php';

                if (file_exists($sFilePathConfig)) {
                    $oApplication->getUrlManager()->addRules(require($sFilePathConfig));
                }
            }
        }
    }
}

Create route file in module folder (/modules/XXX/config/_routes.php)

在模块文件夹中创建路由文件 (/modules/XXX/config/_routes.php)

return [
    '/sales'                            => '/sales/index/index',
    '/sales/company'                    => '/sales/company/index',
    '/sales/company/view/<sID:\d+>'     => '/sales/company/view',
    '/sales/company/update/<sID:\d+>'   => '/sales/company/update',
    '/sales/company/delete/<sID:\d+>'   => '/sales/company/delete',
];

Add boostrap to main config file

将 boostrap 添加到主配置文件

$aConfig = [
    // some code
    'bootstrap' => [
        // some code
        'app\extensions\ModuleBootstrap',
    ],
    'modules' => [
        // some code
        'sales' => ['class' => 'app\modules\sales\SalesModule']
    ]
]

return $aConfig;

That's it. We can define routes only in module 'route' config.

就是这样。我们只能在模块 'route' 配置中定义路由。

PS: I don't like detection if (is_array($aModule) && strpos($aModule['class'], 'app\modules') === 0)(I mean NOT 'debug', 'log', 'gii' or other native Yii2 modules) maybe someone can suggest better solution?

PS:我不喜欢检测if (is_array($aModule) && strpos($aModule['class'], 'app\modules') === 0)(我的意思不是“调试”、“日志”、“gii”或其他本地 Yii2 模块)也许有人可以提出更好的解决方案?

回答by Anil Chaudhari

And this will be more clean and reliable. I have found this on Yii2's github repo here.

这将更加干净和可靠。我在 Yii2 的 github repo here上找到了这个。

<?php
namespace backend\modules\webmasters;

use Yii;
use yii\base\BootstrapInterface;

class Module extends \yii\base\Module implements BootstrapInterface
{
    public $controllerNamespace = 'backend\modules\webmasters\controllers';

    public function init()
    {
        parent::init();
        // initialize the module with the configuration loaded from config.php
        Yii::configure($this, require(__DIR__ . '/config/main.php'));
    }

    /**
     * @inheritdoc
     */
    public function bootstrap($app)
    {
        $app->getUrlManager()->addRules([
            [
                'class' => 'yii\web\UrlRule', 
                'pattern' => $this->id, 
                'route' => $this->id . '/tools/index'
            ],
            [
                'class' => 'yii\web\UrlRule', 
                'pattern' => $this->id . '/<controller:[\w\-]+>/<action:[\w\-]+>', 
                'route' => $this->id . '/<controller>/<action>'
            ],
        ], false);
    }
}

and just configure your main.php config file's bootstrap section as

只需将您的 main.php 配置文件的引导部分配置为

'bootstrap' => [
    'log',
    'webmasters'
]
'modules' => [
    'webmasters' => [
        'class' => 'backend\modules\webmasters\Module'
     ]
]