新版的控制器设计的更为灵活,主要体现在如下几个方面:
* 可以无需继承任何控制器类;
* 控制器操作方法中无需关心输出问题;
* 直接支持在操作方法中操作视图类;
* 可以通过引入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');
~~~