方法簽名
redirect($url, $params = [], $delay = 0, $msg = '')
$url:目標地址,支援多種簡寫格式
$params:URL 參數陣列,自動組裝查詢字串
$delay:延遲秒數,0 為立即跳轉(預設)
$msg:延遲期間顯示訊息
URL 格式完整對照表
| 寫法 | 含義 | 適用版本 |
'edit' | 當前模組當前控制器的 edit 方法 | 所有 |
'User/edit' | 當前模組 User 控制器 edit 方法 | 所有 |
'Admin/' | Admin 分組預設模組預設方法 | 3.x 分組模式 |
'Admin-Index/view' | Admin 分組 Index 控制器 view 方法 | 3.x 分組模式 |
'Admin/Index/view' | 同上(5/6 模組模式) | 5/6 |
['Admin/Index/view', 'uid'=>1] | 帶參數陣列(推薦寫法) | 所有 |
'OtherApp://Admin-User/view' | 跨項目/應用跳轉 | 3.x 多項目 |
U('Admin/Index/view') | 配合 U 函數生成完整 URL | 所有 |
實戰範例
基本跳轉
<?php
// 表單提交成功後跳轉列表頁
$this->redirect('Article/index');
// 刪除後跳轉並攜帶頁碼參數
$this->redirect('Article/index', ['page' => $page, 'cate' => $cate_id]);
延遲跳轉與提示
<?php
// 3 秒後跳轉,顯示友好訊息
$this->redirect('User/profile', ['id' => $uid], 3, '資料更新成功,正在跳轉...');
// 錯誤頁面延遲導回
$this->redirect('Index/error', ['code' => 404], 5, '頁面不存在,5 秒後返回首頁');
跨模組/分組跳轉
<?php
// ThinkPHP 3.x 分組模式
$this->redirect('Admin/User/index'); // Admin 分組 User 控制器
$this->redirect('Admin-User/index'); // 同義,- 作為分隔符
// ThinkPHP 5/6 模組模式
$this->redirect('admin/user/index'); // 小寫模組/控制器/方法
$this->redirect('api/v1/user/index'); // 多級模組
// 跨應用(需配置多入口)
$this->redirect('api://v1/user/index');
配合路由別名
<?php
// 路由配置
'user_profile' => 'User/profile',
// 控制器中使用路由名稱
$this->redirect('user_profile', ['id' => 123]);
// 等效於
$this->redirect('User/profile', ['id' => 123]);
底層實現原理
<?php
// ThinkPHP 3.2 核心邏輯簡化
protected function redirect($url, $params = [], $delay = 0, $msg = '') {
$url = U($url, $params); // 統一走 U 函數生成最終 URL
if ($delay > 0) {
// 延遲跳轉:輸出跳轉頁面(含 meta refresh + JS 備援)
$this->assign('waitSecond', $delay);
$this->assign('jumpUrl', $url);
$this->assign('message', $msg ?: "頁面將在 {$delay} 秒後跳轉...");
$this->display('Public:dispatch_jump'); // 系統預設跳轉模板
exit;
} else {
// 立即跳轉:HTTP 302 Header
header("Location: $url");
exit;
}
}
常見坑點與避雷
| 問題 | 原因 | 解決 |
| 跳轉後參數丟失 | 手動拼接 URL 未 urlencode | 使用 $params 陣列自動編碼 |
| 延遲跳轉不顯示訊息 | 模板變數未賦值/自定義模板缺失 | 檢查 dispatch_jump 模板變數:$waitSecond, $jumpUrl, $message |
| 跨分組跳轉 404 | 分組名稱大小寫/拼寫錯誤 | 確認分組目錄結構、APP_DEBUG 開啟排查 |
| AJAX 請求 redirect 失效 | 瀏覽器跟隨 302 導致回應被 JS 接收而非跳轉 | AJAX 回傳 JSON {url: '...'} 由前端 window.location.href 跳轉 |
| Header already sent | redirect 前有 echo/空白輸出 | ob_start() 或調整代碼順序 |
AJAX 專用跳轉模式
<?php
// 控制器判斷 AJAX 請求
if (IS_AJAX) {
$this->ajaxReturn([
'status' => 1,
'url' => U('User/index'),
'msg' => '操作成功'
]);
} else {
$this->redirect('User/index', [], 1, '操作成功');
}
// 前端統一處理
$.ajax({
// ...
success: function(res) {
if (res.url) {
setTimeout(() => location.href = res.url, 1000);
}
}
});
最佳實踐總結
- 優先使用陣列參數:
redirect('User/edit', ['id' => $id]) 而非字串拼接
- 延遲跳轉慎用:現代 SPA 架構下由前端控制跳轉體驗更好
- 統一跳轉模板:覆蓋
Tpl/dispatch_jump.tpl 符合品牌風格
- 區分 AJAX/普通請求:返回 JSON 讓前端決定行為
- 安全跳轉:避免開放式重定向漏洞,驗證 $url 白名單
redirect() 是 ThinkPHP 控制器流程控制的核心方法,理解其 URL 解析規則、延遲機制、跨模組語法,能讓你在複雜業務流程中靈活導向,避免硬編碼 URL 帶來的維護噩夢。