Yii2:从模块路由中省略控制器 ID
Yii2: Omit controller ID from module route
模块控制器中任何动作的典型 Yii2 路由如下:
<moduleID>/<controllerID>/<actionID>
我们如何 configure/structure 我们的模块(只有 1 个控制器),以便我们可以使用以下路径直接到达其操作:
<moduleID>/<actionID>
无需覆盖主应用程序的 urlManager?
中的路由
如果 "without having to override the routes in the main application's urlManager" 你的意思是不修改 urlManager 路由,我认为这是不可能的。
但如果你只是想说 "without new route rules added in app's configuration file" 方法如下:
您可以通过在模块内部设置规则来实现。
将您的模块添加到配置的 bootstrap
部分(如果尚不存在)。
现在在主模块的文件中(默认 Module.php)添加:
public function bootstrap($app)
{
if ($app instanceof \yii\web\Application) {
$app->urlManager->addRules([
['your-module/<action>' => 'your-module/controllers-name/<action>'],
]);
}
}
除了 Bizley 的回答之外,您还可以在模块中使用特定于模块的 url 规则创建单独的配置文件,例如:
modules/<moduleID>/config/url-rules.php
然后在模块 bootstrap 方法中加载这些规则(如 Bizley 所示)。
然后你可以在主应用程序中自动扫描可用模块和类似的配置文件,并将这些 url 规则与通用应用程序配置合并。
此外,在加载模块时防止重复这些规则也很重要。
我不喜欢这种方法,因为它破坏了 "modularity",但是它可以在没有 bootstrapping 所有模块的情况下工作(这非常节省内存)。
结合 and 的答案并加入我自己的一些智慧,我想出了一个解决方案。只要您的模块是通过 composer 添加的,您就可以这样做:
在您的模块中创建一个包含以下内容的 RouteBootstrap.php
文件:
namespace your\name\space;
class RouteBootstrap implements \yii\basic\BootstrapInterface {
public function bootstrap($app) {
if ($app instanceof \yii\web\Application) {
$app->urlManager->addRules([
['moduleID/<action>' => 'moduleID/default/<action>'],
]);
}
}
}
(请务必将 moduleID 替换为您实际的模块 ID)。这是Yii2 Gii官方模块使用的same technique
将以下内容添加到模块的 composer.json
文件中:
"extra": {
"bootstrap": "your\name\space\RouteBootstrap"
}
有关此技巧的更多详细信息,请参阅 documentation。
从您的 vendors
目录和 运行 composer update
中删除模块。
就是这样。您的模块会自动将路由规则添加到主应用程序,您将能够使用 <moduleID>/<actionID>
路由访问 DefaultController 的操作。
另一方面,这仍然不是理想的解决方案。它更像是 Yii2 设计缺陷的变通方法。如果有人提出更好的解决方案,它将被设置为已接受的答案。
模块控制器中任何动作的典型 Yii2 路由如下:
<moduleID>/<controllerID>/<actionID>
我们如何 configure/structure 我们的模块(只有 1 个控制器),以便我们可以使用以下路径直接到达其操作:
<moduleID>/<actionID>
无需覆盖主应用程序的 urlManager?
中的路由如果 "without having to override the routes in the main application's urlManager" 你的意思是不修改 urlManager 路由,我认为这是不可能的。
但如果你只是想说 "without new route rules added in app's configuration file" 方法如下:
您可以通过在模块内部设置规则来实现。
将您的模块添加到配置的 bootstrap
部分(如果尚不存在)。
现在在主模块的文件中(默认 Module.php)添加:
public function bootstrap($app)
{
if ($app instanceof \yii\web\Application) {
$app->urlManager->addRules([
['your-module/<action>' => 'your-module/controllers-name/<action>'],
]);
}
}
除了 Bizley 的回答之外,您还可以在模块中使用特定于模块的 url 规则创建单独的配置文件,例如:
modules/<moduleID>/config/url-rules.php
然后在模块 bootstrap 方法中加载这些规则(如 Bizley 所示)。 然后你可以在主应用程序中自动扫描可用模块和类似的配置文件,并将这些 url 规则与通用应用程序配置合并。 此外,在加载模块时防止重复这些规则也很重要。
我不喜欢这种方法,因为它破坏了 "modularity",但是它可以在没有 bootstrapping 所有模块的情况下工作(这非常节省内存)。
结合
在您的模块中创建一个包含以下内容的
RouteBootstrap.php
文件:namespace your\name\space; class RouteBootstrap implements \yii\basic\BootstrapInterface { public function bootstrap($app) { if ($app instanceof \yii\web\Application) { $app->urlManager->addRules([ ['moduleID/<action>' => 'moduleID/default/<action>'], ]); } } }
(请务必将 moduleID 替换为您实际的模块 ID)。这是Yii2 Gii官方模块使用的same technique
将以下内容添加到模块的
composer.json
文件中:"extra": { "bootstrap": "your\name\space\RouteBootstrap" }
有关此技巧的更多详细信息,请参阅 documentation。
从您的
vendors
目录和 运行composer update
中删除模块。
就是这样。您的模块会自动将路由规则添加到主应用程序,您将能够使用 <moduleID>/<actionID>
路由访问 DefaultController 的操作。
另一方面,这仍然不是理想的解决方案。它更像是 Yii2 设计缺陷的变通方法。如果有人提出更好的解决方案,它将被设置为已接受的答案。