新版的控制器設計的更為靈活,主要體現在如下幾個方面:
* 可以無需繼承任何控制器類;
* 控制器操作方法中無需關心輸出問題;
* 直接支持在操作方法中操作視圖類;
* 可以通過引入Traits或者繼承擴展類的方式來增加控制器功能;
* 支持任意層次的控制器類設計;
## 新的控制器輸出和渲染方式
### 新的控制器輸出方式
新版的控制器設計本身和視圖類以及模型類沒有任何的綁定,操作方法中只需要返回需要輸出的數據(包括字符串和數組,甚至是對象),例如:
~~~
namespace app\index\controller;
class Index {
public function index(){
return 'hello,world!';
}
}
~~~
這是一個典型的控制器類和操作方法定義,雖然我們也可以采用下面的方式,但并不建議:
~~~
namespace app\index\controller;
class Index {
public function index(){
echo 'hello,world!';
}
}
~~~
采用前面一種返回數據的方式有利于你根據需要輸出不同的格式,以及進行統一的攔截處理。
> 控制器的輸出由系統的\Think\Response類接管了,并且由default_return_type參數配置決定輸出的格式,包括json、xml等。
### 模板渲染
如果你需要在控制器的操作方法中渲染模板進行輸出,可以使用下面兩種方式:
#### 一、繼承系統封裝的\Think\Controller類
~~~
namespace app\index\controller;
use think\Controller;
class Index extends Controller {
public function index(){
$this->assign('name','thinkphp');
return $this->fetch('hello');
}
}
~~~
fetch('hello')方法默認會讀取下面的模板文件渲染輸出:
~~~
application/index/view/index/hello.html
~~~
如果使用空的fetch()方法的話則會渲染輸出:
~~~
application/index/view/index/index.html
~~~
如果你不是渲染模板,而是直接渲染內容解析模板標簽進行輸出的話,可以使用show方法,例如:
~~~
namespace app\index\controller;
use think\Controller;
class Index extends Controller {
public function index(){
$this->assign('name','thinkphp');
return $this->show('hello,{$name}');
}
}
~~~
#### 二、直接實例化View類
我們把前面的例子改成直接實例化View類的方式如下:
~~~
namespace app\index\controller;
class Index {
public function index(){
$View = new \Think\View();
$View->assign('name','thinkphp');
return $View->fetch('hello');
}
}
~~~
#### 三、引入Traits的方式擴展
新版的ThinkPHP大量采用了Traits的方式進行擴展和引入,這對功能的組裝帶來極大的便利,同樣,我們把上面的示例改造為引入traits的方式:
~~~
namespace app\index\controller;
// 引入Traits類(PHP5.5以上版本可以不需要)
T('controller/View');
class Index {
use \traits\controller\View;
public function index(){
$this->assign('name','thinkphp');
return $this->fetch('hello');
}
}
~~~
引入Traits的優勢是你可以同時引入多個Traits,不受PHP類只能繼承一個的限制,例如:
~~~
namespace app\index\controller;
// 引入Traits類(PHP5.5以上版本可以不需要)
T('controller/View');
T('controller/Jump');
class Index {
use \traits\controller\View;
use \traits\controller\Jump;
public function index(){
if(!IS_AJAX){
$this->error('非法操作');
}else{
$this->assign('name','thinkphp');
return $this->fetch('hello');
}
}
}
~~~
## 控制器層次
新版的控制器可以支持任意層次的設計,并且沒有相同層次的限制,例如下面定義了一個 index\controller\one\two\Index 控制器類:
~~~
namespace app\index\controller\one\two;
class Index {
public function index(){
return 'hello,world!';
}
}
~~~
我們在訪問該控制器的時候可以使用
~~~
http://serverName/index.php/index/one.two.index/index
~~~
當然,也可以用路由簡化URL,如下:
~~~
\Think\Route::register('hello','index/one.two.index/index');
~~~