Yii2中redirect()必须return,否则不跳转;支持数组(推荐)、字符串、绝对URL三种路径格式;默认302跳转,301需显式传参;无需手动end()。

Yii2里redirect()必须返回响应对象
很多人写完$this->redirect(['site/index'])就结束,结果页面没跳转、也没报错——因为没return。Yii2的redirect()只是设置响应头和状态码,不自动终止执行。漏掉return会导致后续代码继续运行,甚至可能抛出Headers already sent错误。
正确写法必须带return:
return $this->redirect(['site/index']);
- 不加
return→ 控制器继续往下走,跳转失效 - 在
if分支里调用 → 每个分支都得return,否则可能执行到后面逻辑 - 放在
beforeAction()里也一样要return
路径写法:数组 vs 字符串 vs 绝对URL
redirect()第一个参数支持三种格式,行为和安全性不同:
- 数组形式:
['post/view', 'id' => 123]→ 自动路由解析,带CSRF防护(默认开启),最推荐 - 字符串路径:
'/admin/user'→ 不经过路由,直接拼到base URL后,易被构造恶意跳转 - 完整URL:
'https://example.com/login'→ 会触发302跳转,但需确认isAbsoluteUrl()校验是否开启(默认开启,会拦截非白名单协议)
如果要用外部URL,得先配置白名单:
'components' => [
'response' => [
'on beforeSend' => function ($event) {
$response = $event->sender;
if ($response->statusCode == 302 && !empty($response->headers->get('Location'))) {
// 自定义校验逻辑
}
}
]
]
更简单的方式是重写redirect()时传['absolute' => true]并确保域名在Url::setHostInfo()中已设好。
跳转前要Yii::$app->end()吗?
不需要,也不应该手动调用Yii::$app->end()。Yii2的redirect()内部已通过Response::send()完成输出,并在Application::run()流程中自然退出。手动end()会导致PHP进程提前终止,可能跳过日志写入、DB事务提交、事件触发等关键收尾操作。
- 只有在极少数自定义SAPI或CLI场景下才需
end(),Web请求完全不用 - 若发现跳转后页面空白或部分渲染,大概率是
redirect()之后又echo了内容,或有输出缓冲未清理 - 调试时可用
var_dump($this->response->getHeaders()->get('Location'));确认跳转地址是否已设置
301永久跳转和带参数的临时跳转怎么写
默认redirect()发302,想发301就传第二个参数:
return $this->redirect(['user/profile'], 301);
带查询参数(比如提示消息)推荐用setFlash()配合跳转:
$this->view->params['returnUrl'] = Yii::$app->request->url;
Yii::$app->session->setFlash('success', '操作成功');
return $this->redirect(['site/index']);
- 不要把敏感参数拼在URL里跳转(如
redirect(['order/pay', 'token' => $t])),容易泄露 - 301跳转会缓存,改需求后浏览器可能仍跳旧地址,上线后留意缓存影响
- 移动端WebView对301处理不一致,涉及微信/支付宝回调页建议坚持用302
跳转本身很简单,但参数来源、状态码选择、响应生命周期这几个点一旦忽略,问题往往出现在上线后才暴露。


















