ThinkPHP 提供「空操作」與「空控制器」機制,讓開發者優雅處理不存在的 Action、實現動態頁面渲染、統一 404 錯誤頁。本文詳細說明觸發條件、優先級、實戰範例與常見誤區。
| 機制 | 觸發條件 | 用途 |
|---|---|---|
空操作 _empty() | 控制器存在,但請求的 Action 方法不存在 | 動態頁面渲染、統一 404、參數化路由 |
空控制器 EmptyController (或 EmptyAction) | 請求的控制器類不存在 | 全域 404、模塊級 fallback |
_empty() 實戰訪問 https://localhost/yiyunmap/map/test
MapController 存在testAction 方法Map/test.htmlThinkPHP 會自動渲染該模板,**無需定義任何方法**。
<?php
// CommonAction.class.php - 所有控制器繼承此基類
class CommonAction extends Action {
public function _empty($name) {
// $name 為請求的操作名
header("HTTP/1.0 404 Not Found");
$this->display('Public:404'); // 渲染統一 404 模板
exit;
}
}
// IndexAction.class.php
class IndexAction extends CommonAction {
// 繼承後,所有不存在的操作自動走 _empty()
}
?>
EmptyController當訪問不存在的控制器 (如 https://site/NotExist/index) 時觸發。
<?php
// 定義在模塊 Controller 目錄下
class EmptyAction extends Action { // TP3.x 命名
public function index() {
header("HTTP/1.0 404 Not Found");
$this->display('Public:404');
}
// 也可定義 _empty() 處理該空控制器下的所有操作
public function _empty($name) {
$this->index();
}
}
?>
_empty($actionName)EmptyAction → 執行 index() 或 _empty()| 誤區 | 正確做法 |
|---|---|
以為定義 EmptyAction 就夠了 | **每個控制器**都需定義 _empty() 或繼承含 _empty() 的基類 |
_empty() 內直接 header('Location: /404.html') | 若需保持 URL 不變、返回 404 狀態碼,請用 $this->display('404') + header('HTTP/1.0 404 Not Found') |
| 所有頁面空白 | 檢查 APP_DEBUG 是否關閉、Runtime 目錄權限、模板路徑大小寫 (Linux 區分大小寫) |
<?php
class PageAction extends CommonAction {
public function _empty($page) {
// URL: /page/about → $page = 'about'
// URL: /page/contact-us → $page = 'contact-us'
$allowed = ['about', 'contact', 'privacy', 'terms'];
if (in_array($page, $allowed)) {
$this->display("Page:$page"); // 渲染 Page/about.html 等
} else {
$this->_empty('404'); // 觸發基類 404
}
}
}
?>
善用 _empty() 與 EmptyAction,能將「不存在的請求」轉化為「動態渲染機會」或「優雅的 404 體驗」。記住:基類統一 404、模板檔案按模塊/控制器/操作命名、Linux 環境注意大小寫,即可避開 90% 的坑。