简介
ThinkPHP 5.0 的控制器定义比较灵活,可以无需继承任何的基础类,也可以继承官方封装的 \think\Controller 类或者其他的控制器类。
一个典型的控制器类定义如下:
<?php
namespace app\index\controller;
class Blog
{
public function index()
{
return view('index');
}
}
控制器类文件的实际位置是 application\index\controller\Blog.php。
控制器类可以无需继承任何类,命名空间默认以 app 为根命名空间。
默认情况下,控制器的输出全部采用 return 的方式,无需进行任何的手动输出,系统会自动完成渲染内容的输出。
ThinkPHP 5.0 中,控制器主要分为以下几种:
- 访问控制器(主控制器)
- 空控制器
- 多级控制器
- 分层控制器
- Rest 控制器
- 资源控制器
访问控制器
可通过 URL 直接访问的控制器就是访问控制器(Controller)或者主控制器,访问控制器是由 \think\App 类负责调用和实例化的,无需手动实例化。
URL 解析和路由后,会把当前的 URL 地址解析到 [ 模块/控制器/操作 ],其实也就是执行某个控制器类的某个操作方法。
上面的一段代码,就是一个访问控制器的例子。可访问的 URL 为:http://serverName/index/blog/index
空控制器
空控制器是指当系统找不到指定的控制器名称的时候,系统会尝试定位到空控制器(Error),利用这个机制可以用来定制错误页面和URL优化。
默认的空控制器的名称为 Error。
我们给项目定义一个Error控制器类。
<?php
namespace app\index\controller;
use think\Request;
class Error
{
public function index(Request $request)
{
$controllerName = $request->controller();
return $controllerName.'不存在';
}
}
多级控制器
多级控制器是指在application\index\controller目录中,创建子目录,用于存放控制器类文件。
ThinkPHP5.0 支持任意层次级别的控制器,并且支持路由。例如:
<?php
namespace app\index\controller\api;
class Blog
{
public function index()
{
return view('index');
}
}
该控制器类的文件位置为:application/index/controller/api/Blog.php。
可访问的URL为:http://serverName/index.php/index/api.blog/index
修改配置文件,设置controller_auto_search参数开启自动定位控制器,便于URL访问。
'controller_auto_search' => true,
之后,就可以使用这个URL地址:http://serverName/index.php/index/api/blog/index
分层控制器
分层控制器是对外隔离的,不能被URL直接访问,只能在访问控制器、模型类的内部,或者视图模板文件中进行调用。
分层控制器的目录和访问控制器的目录平级。
分层控制器可用于实现逻辑层控制器,给访问控制器调用;或者用于实现widget(挂件)功能,给视图模板调用,如更改网站皮肤、显示菜单、面包屑、公共头中的信息、广告位等等。
逻辑控制器
利用分层控制器的机制,我们定义Blog逻辑控制器。
<?php
namespace app\index\logic;
class Blog
{
public function insert($data)
{
// 逻辑层代码
return true;
}
}
在访问控制器或模型类中的调用方式如下:
$logic = \think\Loader::controller('Blog', 'logic');
$logic->insert($data);
或
$logic = controller('Blog', 'logic');
$logic->insert($data);
或
action('Blog/insert', ['data' => $data], 'logic');
支持跨模块调用,例如:
$logic = controller('Admin/Blog', 'logic');
$logic->insert($data);
widget 挂件控制器
利用分层控制器的机制,我们定义widget挂件控制器。
<?php
namespace app\index\widget;
class User
{
public function info()
{
$user_id = session('user.id'); // 获取用户的id
$userinfo = db('user')->where('id', $user_id)->find();
return view("widget/info", ['userinfo' => $userinfo])->getContent();
}
}
在模板中的调用方式如下:
{:action('User/info', '', 'widget')}
或
{:widget('User/info')}
Rest 控制器
如果需要让你的控制器支持 RESTful 的话,可以使用 Rest 控制器,在定义访问控制器的时候直接继承 think\controller\Rest 即可。
新版不再推荐使用 Rest 控制器,建议用资源控制器替代。下一个大版本即将废弃 Rest 控制器。
配合示例需要,首先在应用配置文件中添加:
// URL伪静态后缀
'url_html_suffix' => 'html|xml|json|jsonp',
RESTFul方法和标准模式的操作方法定义主要区别在于,需要对请求类型和资源类型进行判断,大多数情况下,通过路由定义可以把操作方法绑定到某个请求类型和资源类型。如果你没有定义路由的话,需要自己在操作方法里面添加判断代码,示例:
<?php
namespace app\index\controller;
use think\controller\Rest;
class Blog extends Rest
{
public function index()
{
switch ($this->method){
case 'get': // get请求处理代码
if ($this->type == 'json'){
}elseif ($this->type == 'xml'){
}
break;
case 'post': // post请求处理代码
break;
case 'put': // put请求处理代码
break;
default:
break;
}
}
}
在Rest操作方法中,可以使用$this->type获取当前访问的资源类型,用$this->method获取当前的请求类型。
RESTFul 输出,有以下三种方式:
使用Rest类提供的 response 方法,进行输出:
$this->response($data, 'json', );
使用think\Response类中的方法,进行输出:
Response::create($data, 'json')->code();
使用助手函数,进行输出:
资源控制器
资源控制器可以轻松的创建 RESTFul 资源控制器,可以通过命令行创建资源控制器。
// 生成 index 模块的 Blog 资源控制器
php think make:controller index/Blog
或者使用完整的命名空间生成。
php think make:controller app\index\controller\Blog
为资源控制器注册一个资源路由。
Route::resource('blog','index/Blog');
设置后会自动注册 7 个路由规则,如下:
请求类型 | 路由规则 | 对应的方法 | 说明 |
---|---|---|---|
GET | blog | index | 文章列表页(首页) |
GET | blog/create | create | 创建新文章的界面 |
POST | blog | save | 执行创建新文章 |
GET | blog/:id | read | 查看指定的文章 |
GET | blog/:id/edit | edit | 更新文章的界面 |
PUT | blog/:id | update | 执行更新文章 |
DELETE | blog/:id | delete | 执行删除文章 |
推荐使用资源控制器,来进行增、删、改、查的操作。