# 快速入門(十八):多層控制器
ThinkPHP支持多層業(yè)務(wù)控制器的支持,給中大型應(yīng)用提供了方便。
## 定義多層控制器
我們通常所了解的控制器其實(shí)是Controller控制器類,而且大多數(shù)也是繼承了核心的Think\Controller類,由于該類控制器是通過URL訪問請求后調(diào)用的,因此也稱之為訪問控制器,事實(shí)上,ThinkPHP可以支持更多的控制器分層,多層控制器的定義完全取決于項(xiàng)目的需求,例如我們可以分為業(yè)務(wù)控制器和事件控制器:
> Home\Controller\UserController //用于用戶的業(yè)務(wù)邏輯控制和調(diào)度
> Home\Event\UserEvent //用于用戶的事件響應(yīng)操作
~~~
├─Controller 訪問控制器
│ ├─UserController.class.php
│ ...
├─Event 事件控制器
│ ├─UserEvent.class.php
│ ...
~~~
一個(gè)標(biāo)準(zhǔn)的訪問控制器定義如下:
~~~
namespace Home\Controller;
class UserController extend Think\Controller {
// 默認(rèn)操作方法
public function index(){
//...
}
// 用戶注冊操作方法
public function register(){
//...
}
}
~~~
> 注:訪問控制器的名稱并非一定是Controller,而是通過DEFAULT_C_LAYER設(shè)置的,默認(rèn)設(shè)置是Controller。
訪問控制器負(fù)責(zé)外部的交互響應(yīng),通過URL請求調(diào)用,例如:
~~~
http://serverName/Home/User/index
http://serverName/Home/User/register
~~~
而事件控制器負(fù)責(zé)內(nèi)部的事件響應(yīng),并且只能在內(nèi)部調(diào)用,所以是和外部隔離的。
> 確切的說,所有訪問控制器之外的分層控制器都只能內(nèi)部實(shí)例化調(diào)用。
~~~
namespace Home\Event;
class UserEvent {
// 用戶登錄事件
public function login(){
echo 'login event';
}
// 用戶登出事件
public function logout(){
echo 'logout event';
}
}
~~~
> 如果是定義其他的控制器層,則不一定必須要繼承系統(tǒng)的Controller類或其子類,通常需要輸出模版的時(shí)候才需要繼承Controller類。
## 調(diào)用多層控制器
訪問控制器是通過URL請求調(diào)用,訪問控制器之外的分層控制器都只能內(nèi)部調(diào)用,調(diào)用多層控制器可以通過兩種方式:
### 直接實(shí)例化
~~~
namespace Home\Controller;
class UserController extend Think\Controller {
// 默認(rèn)操作方法
public function index(){
// 觸發(fā)事件
$event = new \Home\Event\UserEvent();
$event->login();
}
}
~~~
### A函數(shù)實(shí)例化
~~~
namespace Home\Controller;
class UserController extend Think\Controller {
// 默認(rèn)操作方法
public function index(){
// 觸發(fā)事件
$event = A('User','Event');
$event->login();
// 或者直接使用
// R('User/login','','Event');
}
}
~~~
## Widget實(shí)例
Widget類的實(shí)現(xiàn)可以作為分層控制器的另外一個(gè)典型實(shí)例。
舉個(gè)例子,我們在頁面中實(shí)現(xiàn)一個(gè)分類菜單的Widget,首先我們要定義一個(gè)Widget控制器層 MenuWidget,如下:
~~~
namespace Home\Widget;
class MenuWidget extends Think\Controller {
public function index(){
echo 'menuWidget';
}
}
~~~
類文件位于 `Home/Widget/MenuWidget.class.php`。
然后,我們在需要顯示分類菜單的模版中通過W方法調(diào)用這個(gè)Widget。
~~~
{~W('Menu/index')}
~~~
執(zhí)行后的輸出結(jié)果是: menuWidget
如果需要在調(diào)用Widget的時(shí)候傳入?yún)?shù),可以這樣定義:
~~~
namespace Home\Widget;
class MenuWidget extends Think\Controller {
public function index($id,$name){
echo $id.':'.$name;
}
}
~~~
在需要顯示分類菜單的模版中添加如下的Widget調(diào)用代碼如下:
~~~
{~W('Menu/index',array(5,'thinkphp'))}
~~~
則會輸出 5:thinkphp
來一個(gè)復(fù)雜一點(diǎn)的例子:
~~~
namespace Home\Widget;
class MenuWidget extends Think\Controller {
public function index(){
$menu = M('Cate')->getField('id,title');
$this->assign('menu',$menu);
$this->display('Widget/menu');
}
}
~~~
CateWiget類渲染了一個(gè)模版文件 `Home/View/Widget/menu.html`,
在menu.html模版文件中的用法:
~~~
<foreach name="menu" item="title">
{$key}:{$title}
</foreach>
~~~
- 快速入門 1:基礎(chǔ)
- 快速入門 2:CURD
- 快速入門 3:查詢語言
- 快速入門 4:連貫操作
- 快速入門 5:變量
- 快速入門 6:路由
- 快速入門 7:視圖
- 快速入門 8:變量輸出
- 快速入門 9:循環(huán)和控制輸出
- 快速入門 10:公共模板和模板布局
- 快速入門 11:Action參數(shù)綁定
- 快速入門 12:空操作和空控制器
- 快速入門 13:初始化、前置和后置操作
- 快速入門 14:頁面跳轉(zhuǎn)和重定向
- 快速入門 15:頁面請求和AJAX
- 快速入門 16:偽靜態(tài)
- 快速入門 17:操作綁定到類
- 快速入門 18:多層控制器
- 快速入門 19:自動驗(yàn)證
- 快速入門 20:自動完成
