ThinkPHP 404/錯誤/成功提示頁面自定義完整指南:配置、模板、變數與最佳實踐
ThinkPHP 提供 _404()、halt()、success()、error() 等方法處理錯誤與提示,支援自定義模板。本文完整說明配置方法、模板變數、自定義範例與 AJAX 處理技巧。
核心方法對照
| 方法 | 用途 | 參數 | 預設模板 |
_404($msg, $url) | 404 錯誤頁面 | 訊息、跳轉網址 | TMPL_EXCEPTION_FILE |
halt($msg) | 嚴重錯誤停止執行 | 訊息 | TMPL_EXCEPTION_FILE |
success($msg, $url, $wait) | 成功提示並跳轉 | 訊息、跳轉網址、等待秒數 | dispatch_jump.tpl |
error($msg, $url, $wait) | 錯誤提示並跳轉 | 訊息、跳轉網址、等待秒數 | dispatch_jump.tpl |
配置自定義錯誤模板
<?php
// Conf/config.php
return [
// 例外/錯誤頁面模板
'TMPL_EXCEPTION_FILE' => './Public/Tpl/error.html',
// 成功/錯誤跳轉頁面模板
'TMPL_ACTION_SUCCESS' => './Public/Tpl/success.html',
'TMPL_ACTION_ERROR' => './Public/Tpl/error.html',
// AJAX 回傳格式
'DEFAULT_AJAX_RETURN' => 'JSON',
];
自定義錯誤頁面模板範例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>系統提示</title>
<style>
body { font-family: 'Microsoft YaHei', sans-serif; text-align: center; background: #f5f5f5; padding-top: 100px; margin: 0; }
.container { max-width: 400px; margin: 0 auto; background: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 40px; }
.icon { font-size: 64px; margin-bottom: 20px; }
.success { color: #28a745; }
.error { color: #dc3545; }
h1 { font-size: 24px; margin-bottom: 10px; color: #333; }
p { color: #666; line-height: 1.6; }
.countdown { color: #999; font-size: 14px; margin-top: 20px; }
a { color: #007bff; text-decoration: none; }
a:hover { text-decoration: underline; }
.btn { display: inline-block; padding: 10px 20px; background: #007bff; color: white; border-radius: 4px; margin-top: 15px; }
</style>
</head>
<body>
<div class="container">
<present name="message">
<div class="icon success">✓</div>
<h1>操作成功</h1>
<else/>
<div class="icon error">✗</div>
<h1>操作失敗</h1>
</present>
<p><?php echo $message; ?></p>
<div class="countdown">
<?php if ($waitSecond > 0): ?>
{$waitSecond} 秒後自動跳轉,或
立即跳轉
停止
<?php else: ?>
前往頁面
<?php endif; ?>
</div>
</div>
<script>
var wait = {$waitSecond};
var url = '{$jumpUrl}';
var timer;
function startCountdown() {
if (wait <= 0) return;
timer = setInterval(function() {
wait--;
document.getElementById('countdown').textContent = wait;
if (wait <= 0) {
clearInterval(timer);
window.location.href = url;
}
}, 1000);
}
function stopCountdown() {
clearInterval(timer);
document.getElementById('countdown').parentElement.innerHTML = '已停止自動跳轉,點此前往';
}
startCountdown();
</script>
</body>
</html>
模板可用變數
| 變數 | 說明 | 範例 |
$message | 提示訊息 | 操作成功 |
$jumpUrl | 跳轉目標網址 | /user/profile |
$waitSecond | 等待秒數 | 3 |
$status | 狀態(1成功/0錯誤) | 1 |
控制器中使用範例
<?php
class UserController extends Controller {
public function login() {
if (IS_POST) {
$username = I('post.username');
$password = I('post.password');
if ($user = D('User')->verify($username, $password)) {
session('user', $user);
// 成功:3秒後跳轉到首頁
$this->success('登入成功', U('Index/index'), 3);
} else {
// 錯誤:5秒後跳轉回登入頁
$this->error('帳號或密碼錯誤', U('User/login'), 5);
}
}
$this->display();
}
public function delete($id) {
if (M('User')->delete($id)) {
$this->success('刪除成功', U('User/index'));
} else {
$this->error('刪除失敗');
}
}
public function notFound() {
// 404 頁面
$this->_404('頁面不存在', U('Index/index'));
}
public function fatal() {
// 嚴重錯誤
$this->halt('系統維護中,請稍後再試');
}
}
AJAX 請求自動處理
<?php
// ThinkPHP 自動偵測 AJAX 請求(HTTP_X_REQUESTED_WITH)
// 當為 AJAX 時,success()/error() 直接回傳 JSON 而非跳轉頁面
// 前端
$.post('/user/login', {username: 'test', password: '123'}, function(res) {
// res = {status: 1, info: '登入成功', url: '/', data: {}}
if (res.status) {
alert(res.info);
setTimeout(function() { location.href = res.url; }, 1000);
} else {
alert(res.info);
}
}, 'json');
進階:區分 AJAX 與一般請求的自定義回應
<?php
class BaseController extends Controller {
protected function ajaxSuccess($data = [], $msg = '成功') {
if (IS_AJAX) {
$this->ajaxReturn(['status' => 1, 'msg' => $msg, 'data' => $data]);
} else {
$this->success($msg, $_SERVER['HTTP_REFERER'], 2);
}
}
protected function ajaxError($msg = '失敗', $data = []) {
if (IS_AJAX) {
$this->ajaxReturn(['status' => 0, 'msg' => $msg, 'data' => $data]);
} else {
$this->error($msg, $_SERVER['HTTP_REFERER'], 3);
}
}
}
常見問題排查
| 問題 | 原因 | 解決 |
| 自定義模板不生效 | 路徑錯誤或快取未清除 | 檢查 TMPL_EXCEPTION_FILE 路徑、刪除 Runtime/Cache |
| 跳轉網址錯誤 | U() 方法參數錯誤 | 使用 U('Controller/action', ['param' => 'value']) |
| AJAX 不回傳 JSON | 未偵測到 AJAX 請求 | 確認前端發送 X-Requested-With: XMLHttpRequest 標頭 |
| 模板變數無輸出 | 變數名稱錯誤 | 使用 $message、$jumpUrl、$waitSecond、$status |