Yii2路由定义在模块中

时间:2015-01-14 23:09:28

标签: php routes yii2

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

实施例。我们有描述的主配置

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

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

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

    return $this;
}

配置文件

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

现在我需要以某种方式将当前配置(主要用于Web应用程序)与从模块加载的配置合并。最后,我想在模块配置路由中仅描述此模块,并将它们用于漂亮的URL(用户友好的URL)。我怎么能这样做?此示例在我创建网址/admin/index/index时无效,它向我显示/admin/index/index,但我想要/admin,如模块规则中所述。

3 个答案:

答案 0 :(得分:9)

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

为模块创建特殊的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));
                }
            }
        }
    }
}

在模块文件夹中创建路径文件(/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',
];

将boostrap添加到主配置文件

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

return $aConfig;

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

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

答案 1 :(得分:5)

这将更加干净和可靠。我在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);
    }
}

并将main.php配置文件的bootstrap部分配置为

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

答案 2 :(得分:1)

官方文档here中提到了分离模块的网址规则。

我认为这是一种更好的方法,不像在一个配置文件中合并和声明所有规则。

规则按照声明的顺序进行解析(这被提到here),因此通过分离,您可以跳过其他模块的URL。如果有大量规则,它可以提高性能。