在上一課程中,你可能對 ThinkPHP 的路由機制仍存疑惑,但別擔心,學完本篇關於控制器的詳細講解,許多概念將豁然開朗。
ThinkPHP 遵循 IndexController.class.php 的命名方式,即控制器類名需以 Controller 結尾,檔案名與類名一致。
首先明確控制器的定義規則:
namespace Home\ControllerThink\Controller 基類Controller(或其子類)範例代碼:
<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function read($id){
echo "read page with </br>" . $id;
}
public function top(){
echo "top page </br>";
}
}
如前文路由篇所述,訪問 https://localhost:8999/index.php/Home/Index/top 即會觸發 top() 方法,輸出 "top page"。其中 Home 代表 Home 模組。
若方法名與系統關鍵字衝突,可透過設定操作方法後綴解決,詳見官方文檔:控制器定義。
前置(_before_操作名)與後置(_after_操作名)操作會在執行特定操作方法前後自動調用,僅對控制器訪問有效。例如為 top() 添加前後置方法:
public function _before_top(){ echo "before top page </br>"; }
public function top(){ echo "top page </br>"; }
public function _after_top(){ echo "after top page </br>"; }
訪問 https://localhost:8999/index.php/Home/Index/top 將依序輸出:
before top page top page after top page
注意事項:
exit 或錯誤輸出,可能不再執行後置方法。例如調用系統 Action 的 error 方法將不再執行後置操作,但不影響 success 方法的後置執行。參數綁定將 URL 中的變量直接作為操作方法參數,簡化方法定義與路由解析。預設開啟('URL_PARAMS_BIND' => true),原理是將 URL 參數(不含模組、控制器、操作名)與方法參數綁定。
public function read($id){ echo "read page with </br>".$id; }
public function archive($year, $month){ echo "$year </br>".$month; }
對應路由規則 'blogs/:id' => array('Index/read'),將 :id 映射給 read() 的 $id。若無路由設定,正確訪問為:https://localhost:8999/Home/index/read/id/3。若參數名改為 $title,則訪問 https://localhost:8999/index.php/Home/index/read/title/3。
多參數綁定不拘順序,如下兩 URL 結果相同:
https://localhost:8999/index.php/Home/index/archive/year/2012/month/12https://localhost:8999/index.php/Home/index/archive/month/12/year/2012若訪問 https://localhost:8999/index.php/Home/index/read/ 會報錯「參數錯誤或未定義:id」。解決方法是給參數設定預設值:
public function read($id=0){ echo "read page with </br>".$id; }
若 URL 無顯示變量名(如 https://localhost:8999/index.php/Home/index/read/3),需啟用順序綁定:
'URL_PARAMS_BIND_TYPE' => 1
此模式下 URL 參數順序嚴格對應方法參數順序,不可隨意調整。例如:
https://localhost:8999/index.php/Home/index/archive/2012/12 正確https://localhost:8999/index.php/Home/index/archive/12/2012 結果錯誤為提升 SEO,ThinkPHP 支援偽靜態 URL。透過 URL_HTML_SUFFIX 設定靜態後綴,預設為 html,可自訂:
'URL_HTML_SUFFIX'=>'shtml'
支援多後綴:
'URL_HTML_SUFFIX' => 'html|shtml|xml'
留空則支援所有靜態後綴。亦可設定禁止訪問的後綴(URL_DENY_SUFFIX),優先級高於 URL_HTML_SUFFIX:
'URL_DENY_SUFFIX' => 'pdf|ico|png|gif|jpg'
為配合 URL 模式,ThinkPHP 內建 U 方法動態生成 URL,確保專案移植不受環境影響。
U('地址表達式', ['參數'], ['偽靜態後綴'], ['顯示域名'])
[模組/控制器/操作#錨點@域名]?參數1=值1&參數2=值2...
範例:
U('User/add') 生成 User 控制器 add 操作 URLU('Article/read?id=1') 生成 Article 控制器 read 操作且 id=1 的 URLU('Admin/User/select') 生成 Admin 模組 User 控制器 select 操作 URL第二參數支援陣列與字串,以下三種等效:
U('Article/cate',array('cate_id'=>1,'status'=>1))
U('Article/cate','cate_id=1&status=1')
U('Article/cate?cate_id=1&status=1')
不允許 U('Article/cate/cate_id/1/status/1') 這種路徑式傳參。
若定義路由 'blogs/:id\d'=>'Index/read',則 U('/blogs/1') 生成 https://localhost:8999/index.php/Home/blogs/1。
開發中常用的提示跳轉功能,\Think\Controller 內建 success() 和 error() 方法。
public function user() {
$User = M('User');
$data['username'] = 'Think';
$data['email'] = 'Think@gmail.com';
$result = $User->add($data);
if($result){
$this->success('success', '/Home/User/addUser');
} else {
$this->error('failed');
}
}
M('User') 實例化 User 模型,add() 新增資料。需建立 UserController 及 addUser() 方法。訪問 https://localhost:8999/Home/Index/user 即可看到跳轉效果。
success() 和 error() 參數:提示訊息、跳轉地址、等待秒數(預設 success 1 秒,error 3 秒)。若想簡寫跳轉地址(如 /Article/index),需在入口文件定義 define('BIND_MODULE','Home');。
兩方法對應預設模板均為 THINK_PATH . 'Tpl/dispatch_jump.tpl',可自訂修改。
Controller 類的 redirect() 實現頁面重定向,參數用法同 U 函數:
$this->redirect('/Home/Article/show', array('id' => 2), 3, 'Redirecting...');
停留 3 秒後跳轉至 Article 控制器 show 操作,顯示「Redirecting...」,URL 會改變。測試需在 IndexController 添加 redirectToArticle() 並建立 ArticleController 的 show($id) 方法。
若僅重定向到指定 URL,可用 redirect() 函數(非類方法):
$this->redirect('/Home/Article/show/id/3', 'Redirecting...',3);
註:控制器 redirect() 方法用 URL 規則定義地址,而 redirect() 函數為純 URL 地址。