## 控制器和操作
一般來說,ThinkPHP的控制器是一個類,而操作則是控制器類的一個**公共方法**。
下面就是一個典型的控制器類的定義:
~~~
<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function hello(){
echo 'hello,thinkphp!';
}
}
~~~
`Home\IndexController`類就代表了Home模塊下的Index控制器,而hello操作就是`Home\IndexController`類的hello(公共)方法。
當訪問 `http://serverName/index.php/Home/Index/hello` 后會輸出:
~~~
hello,thinkphp!
~~~
> 注意:如果你設置了操作方法綁定到類,則操作方法對應了一個類(參考[操作綁定到類](1726))。
## 定義控制器
控制器通常需要繼承系統的Controller類或者其子類,例如,下面定義了一個 `\Home\Controller\IndexController` 控制器類:
~~~
<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function hello(){
echo 'hello';
}
public function test(){
echo 'test';
}
}
~~~
控制器的名稱采用駝峰法命名(首字母大寫),控制器文件位于 `Home/Controller/IndexController.class.php`。
IndexController控制器類的hello和test方法就是操作方法,訪問下面的URL地址:
~~~
http://serverName/Home/Index/hello
http://serverName/Home/Index/test
~~~
會分別輸出:
~~~
hello
// 和
test
~~~
操作方法的定義必須是公共方法,否則會報操作錯誤,所以,下面的操作定義只能訪問hello操作,而不能訪問test操作。
~~~
<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function hello(){
echo 'hello';
}
protected function test(){
echo 'test';
}
}
~~~
注意:定義控制器方法的時候,盡量避免和系統的保留方法相沖突(`除非你非常明確自己在做什么`),這些保留方法名包括但不限于:
~~~
display
get
show
fetch
theme
assign
error
success
~~~
因為操作方法就是控制器的一個方法,所以遇到有和系統的關鍵字沖突的方法可能就不能定義了,這個時候我們可以設置操作方法的后綴來解決,例如:
~~~
'ACTION_SUFFIX' => 'Action', // 操作方法后綴
~~~
設置操作方法的后綴為Action,這樣,控制器的操作方法定義調整為:
~~~
<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function listAction(){
echo 'list';
}
public function helloAction(){
echo 'hello';
}
public function testAction(){
echo 'test';
}
}
~~~
> 操作方法的后綴設置只是影響控制器類的定義,對URL訪問沒有影響。
## 多層控制器
ThinkPHP的控制器支持多層和多級,多層指的是控制器可以分層,例如除了默認的Controller控制器層(我們可以稱之為訪問控制器),還可以添加事件控制器(層),例如:
~~~
├─Controller 訪問控制器
│ ├─UserController.class.php
│ ├─BlogController.class.php
│ ...
├─Event 事件控制器
│ ├─UserEvent.class.php
│ ├─BlogEvent.class.php
│ ...
~~~
> 訪問控制器的名稱是通過**DEFAULT_C_LAYER**設置的,默認是Controller。
訪問控制器負責外部交互響應,通過URL請求響應,例如 `http://serverName/Home/User/index`,而事件控制器負責內部的事件響應,并且只能在內部調用,所以是和外部隔離的。
> 多層控制器的劃分可以根據項目的需要自由分層。
如果是定義其他的控制器層,則不一定必須要繼承系統的Controller類或其子類,通常需要輸出模版的時候才需要繼承Controller類。例如:
~~~
<?php
namespace Home\Event;
class UserEvent {
public function login(){
echo 'login event';
}
public function logout(){
echo 'logout event';
}
}
~~~
UserEvent事件控制器位于 `Home/Event/UserEvent.class.php` 。
## 多級控制器
多級控制器是指控制器可以通過子目錄把某個控制器層分組存放,首先需要設置控制器的分級層次,例如,我們設置2級目錄的控制器層:
~~~
'CONTROLLER_LEVEL' => 2,
~~~
控制器文件的位置放置如下:
~~~
├─Controller 訪問控制器
│ ├─User User分級(組)
│ │ ├─UserTypeController.class.php
│ │ ├─UserAuthController.class.php
│ ...
│ ├─Admin Admin分級(組)
│ │ ├─UserController.class.php
│ │ ├─ConfigController.class.php
│ ...
~~~
多級控制器中的命名空間需要這樣定義:
~~~
<?php
namespace Home\Controller\Admin;
use Think\Controller;
class IndexController extends Controller {
public function hello(){
echo 'hello';
}
public function test(){
echo 'test';
}
}
~~~
然后就可以通過URL地址訪問:
~~~
http://serverName/Home/User/UserType
http://serverName/Home/Admin/User
~~~
> 如果希望簡化URL地址中的模塊地址,可以參考 [模塊部署](1867)
## 實例化控制器
訪問控制器的實例化通常是自動完成的,系統會根據URL地址解析出訪問的控制器名稱自動實例化,并且調用相關的操作方法。
如果你需要跨控制器調用的話,則可以單獨實例化:
~~~
// 實例化Home模塊的User控制器
$User = new \Home\Controller\UserController();
// 實例化Admin模塊的Blog控制器
$Blog = new \Admin\Controller\BlogController();
~~~
系統為上面的控制器實例化提供了一個快捷調用方法A,上面的代碼可以簡化為:
~~~
// 假設當前模塊是Home模塊
$User = A('User');
$Blog = A('Admin/Blog');
~~~
默認情況下,A方法實例化的是默認控制器層(Controller),如果你要實例化其他的分層控制器的話,可以使用:
~~~
// 假設當前模塊是Home模塊
// 實例化Event控制器
$User = A('User','Event');
$Blog = A('Admin/Blog','Event');
~~~
上面的代碼等效于:
~~~
// 實例化Home模塊的User事件控制器
$User = new \Home\Event\UserEvent();
// 實例化Admin模塊的Blog事件控制器
$Blog = new \Admin\Event\BlogEvent();
~~~
- 序言
- 基礎
- 獲取ThinkPHP
- 環境要求
- 目錄結構
- 入口文件
- 自動生成
- 模塊
- 控制器
- 開發規范
- 配置
- 配置格式
- 配置加載
- 讀取配置
- 動態配置
- 擴展配置
- 批量配置
- 架構
- 模塊化設計
- URL模式
- 多層MVC
- CBD模式
- 命名空間
- 自動加載
- 應用模式
- 項目編譯
- 系統流程
- 路由
- 路由定義
- 規則路由
- 正則路由
- 靜態路由
- 閉包支持
- 實例說明
- 控制器
- 控制器定義
- 前置和后置操作
- Action參數綁定
- 偽靜態
- URL大小寫
- URL生成
- AJAX返回
- 跳轉和重定向
- 輸入變量
- 請求類型
- 空操作
- 空控制器
- 插件控制器
- 操作綁定到類
- 模型
- 模型定義
- 模型實例化
- 字段定義
- 連接數據庫
- 切換數據庫
- 分布式數據庫支持
- 連貫操作
- WHERE
- TABLE
- ALIAS
- DATA
- FIELD
- ORDER
- LIMIT
- PAGE
- GROUP
- HAVING
- JOIN
- UNION
- DISTINCT
- LOCK
- CACHE
- COMMENT
- RELATION
- USING
- fetchSql
- TOKEN
- STRICT
- INDEX
- 命名范圍
- CURD操作
- 數據創建
- 數據寫入
- 數據讀取
- 數據更新
- 數據刪除
- ActiveRecord
- 字段映射
- 查詢語言
- 查詢方式
- 表達式查詢
- 快捷查詢
- 區間查詢
- 組合查詢
- 統計查詢
- SQL查詢
- 動態查詢
- 子查詢
- 自動驗證
- 自動完成
- 參數綁定
- 虛擬模型
- 模型分層
- 視圖模型
- 關聯模型
- 高級模型
- Mongo模型
- 視圖
- 模板定義
- 模板主題
- 模板賦值
- 模板渲染
- 獲取模板地址
- 獲取內容
- 模板引擎
- 模板
- 變量輸出
- 系統變量
- 使用函數
- 默認值輸出
- 使用運算符
- 標簽庫
- 模板繼承
- 修改定界符
- 三元運算
- 包含文件
- 內置標簽
- Volist標簽
- Foreach標簽
- For標簽
- Switch標簽
- 比較標簽
- 范圍判斷標簽
- IF標簽
- Present標簽
- Empty標簽
- Defined標簽
- Assign標簽
- Define標簽
- 標簽嵌套
- import標簽
- 使用PHP代碼
- 原樣輸出
- 模板注釋
- 模板布局
- 模板替換
- 調試
- 調試模式
- 異常處理
- 日志記錄
- 頁面Trace
- Trace方法
- 變量調試
- 性能調試
- 錯誤調試
- 模型調試
- 緩存
- 數據緩存
- 快速緩存
- 查詢緩存
- 靜態緩存
- 安全
- 輸入過濾
- 表單合法性檢測
- 表單令牌
- 防止SQL注入
- 目錄安全文件
- 保護模板文件
- 上傳安全
- 防止XSS攻擊
- 其他安全建議
- 擴展
- 類庫擴展
- 驅動擴展
- 緩存驅動
- 數據庫驅動
- 日志驅動
- Session驅動
- 存儲驅動
- 模板引擎驅動
- 標簽庫驅動
- 行為擴展
- 標簽擴展
- Widget擴展
- 應用模式
- 部署
- PATH_INFO支持
- URL重寫
- 模塊部署
- 域名部署
- 入口綁定
- 替換入口
- 專題
- SESSION支持
- Cookie支持
- 多語言支持
- 數據分頁
- 文件上傳
- 驗證碼
- 圖像處理
- RESTFul
- RPC
- SAE
- IP獲取和定位
- 附錄
- 常量參考
- 配置參考
- 升級指導
- 鳴謝