在我的Yii2配置中,我有:
'components' => [
'urlManager' => [
'baseUrl' => '',
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'search' => 'site/index',
...
],
...
如果我去site.com/search
它就有效。如果我转到site.com/site/index
,它也会起作用并显示相同的内容。如何重定向调用而不是仅显示站点/索引的响应?它还必须使用参数(site.com/site/index?param=1
- > site.com/search?param=1
)
答案 0 :(得分:1)
UrlManager不会重定向。它更像是rewrite,就像一个Web服务器。它被称为routing。
如果您想在代码中进行重定向,可以使用Response::redirect()
。如果您没有SearchController
可以将此语句放入操作中,则可以将其放入beforeAction
事件事件中。您可以在配置数组中执行此操作:
[
'components' = [
...
],
'on beforeAction' => function ($event) {
if(Yii::$app->request->pathInfo === 'search') {
$url = 'site/index?' . Yii::$app->request->queryString;
Yii::$app->response->redirect($url)->send();
$event->handled = true;
}
}
]
或者如果您SearchController
使用:
class SearchController extends \yii\web\Controller {
public function actionIndex() {
$url = 'site/index?' . Yii::$app->request->queryString;
return $this->redirect($url);
}
}
第三个选项是配置Web服务器以执行重定向。那将是最快的解决方案。
答案 1 :(得分:1)
您可以使用UrlManager::$enableStrictParsing
来禁用路由匹配。如果您将其设置为true
,请求/site/index
网址将无法匹配任何内容,应用将返回404错误。
'components' => [
'urlManager' => [
'baseUrl' => '',
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => true,
'rules' => [
'search' => 'site/index',
// ...
],
// ...
但如果你真的想在其他情况下使用路由作为URL,那么这可能不是一个选择。
您可能也对UrlNormalizer
课感兴趣。这仍然是一个相对简单的组件,并且(还)不支持您的用例,但实际上它是专为此类任务而设计的。您可以考虑扩展它并为您的用例添加重定向逻辑 - 它应该比使用事件或专用操作和重定向规则更加清晰。它也可能是PR的一个很好的材料,并将此功能推向核心框架。
延迟解决方案是创建重定向操作并添加规则以匹配需要重定向的URL:
class RedirectController extends Controller {
public function actionRedirect($action, $controller, $module = null) {
if ($action === $this->action->id && $controller === $this->id && $module === null) {
// prevent to access action directly and redirection loops
throw new NotFoundHttpException();
}
$url = Yii::$app->request->get();
unset($url['action'], $url['controller'], $url['module']);
array_unshift($url, '/' . ltrim(implode('/', [$module, $controller, $action]), '/'));
return $this->redirect($url);
}
}
规则:
'urlManager' => [
// ...
'rules' => [
'search' => 'site/index',
[
'pattern' => '<controller:(site)>/<action:(index)>',
'route' => 'redirect/redirect',
'model' => UrlRule::PARSING_ONLY,
],
// ...
],
],
答案 2 :(得分:1)
您可以简单地使用redirect
,就像render
一样简单,它可以解决您的问题。请参见下面的示例:
return $this->redirect(['/site/index']);
P.S。路径可以是绝对路径,也可以是相对路径,也可以使用别名或其他任何方式,这是一个示例:
// an alias of for home page
Yii::setAlias('@home', 'site/index');
答案 3 :(得分:0)
我认为这将更加准确和普遍。在配置中:
'components' => [
],
'on beforeAction' => function ($event) {
list($route, $params) = Yii::$app->urlManager->parseRequest(Yii::$app->request);
$params = $_GET;
if (is_string(Yii::$app->request->pathInfo)
&& strpos(Yii::$app->request->pathInfo, $route) === 0
) {
if (strpos($route, '/') === false) {
$route .= '/index';
}
$url = array_merge([0 => $route], $params);
foreach(Yii::$app->urlManager->rules as $rule) {
if ($rule->route === $route) {
Yii::$app->response->redirect($url)->send();
$event->handled = true;
}
}
}
},