基本概念
个人理解:url访问到的逻辑代码
目录结构
控制器文件通常放在controller下面,类名和文件名保持大小写一致,并采用驼峰命名(首字母大写)。
如果要改变controller目录名,需要在route.php配置文件中设置:
'controller_layer' => 'controllers',
单应用模式
单应用模式控制器的类的定义如下:
<?phpnamespace app\controller;class User{public function login(){return 'login';}}
控制器类文件的实际位置是
app\controller\User.php
访问URL地址是(假设没有定义路由的情况下)
http://localhost/user/login
如果你的控制器是HelloWorld,并且定义如下:
<?phpnamespace app\controller;class HelloWorld{public function hello(){return 'hello,world!';}}
控制器类文件的实际位置是
app\controller\HelloWorld.php
访问URL地址是(假设没有定义路由的情况下)
http://localhost/index.php/HelloWorld/hello
并且也可以支持下面的访问URL
http://localhost/hello_world/hello
多应用模式
多应用模式下,控制器类定义仅仅是命名空间有所区别,例如:
<?phpnamespace app\home\controller;class User{public function login(){return 'login';}}
控制器类文件的实际位置是
app\home\controller\User.php
访问URL地址是(假设没有定义路由的情况下)
http://localhost/index.php/home/user/login
多级控制器(控制器子目录)
支持任意层次级别的控制器,并且支持路由,例如:
<?phpnamespace app\home\controller\user;class Blog{public function index(){return 'index';}}
该控制器类的文件位置为:
app/home/controller/user/Blog.php
访问地址可以使用
http://serverName/home.php/user.blog/index
由于URL访问不能访问默认的多级控制器(可能会把多级控制器名误识别为URL后缀),因此建议所有的多级控制器都通过路由定义后访问,如果要在路由定义中使用多级控制器,可以使用:
Route::get('user/blog/index','user.blog/index');
渲染输出
默认情况下,控制器的输出全部采用return的方式,无需进行任何的手动输出,系统会自动完成渲染内容的输出。
下面都是有效的输出方式:
<?phpnamespace app\index\controller;class Index{public function hello(){// 输出hello,world!return 'hello,world!';}public function json(){// 输出JSONreturn json($data);}public function read(){// 渲染默认模板输出return view();}}
控制器一般不需要任何输出,直接return即可。并且控制器在json请求会自动转换为json格式输出。
不要在控制器中使用包括die、exit在内的中断代码。如果你需要调试并中止执行,可以使用系统提供的halt助手函数。
halt('输出测试');
基础控制器
大多数情况下,我们建议给你的控制器继承一个基础控制器,基础控制器建议按照不同的应用分别设置。
默认安装后,系统提供了一个app\BaseController基础控制器类,你可以对该基础控制器进行修改。
基础控制器的位置可以随意放置,只需要注意更改命名空间即可。
基础控制器模板
<?phpdeclare(strict_types=1);namespace app\home;use think\App;use think\exception\ValidateException;use think\Validate;/*** 控制器基础类*/abstract class BaseController {/*** Request实例* @var \think\Request*/protected $request;/*** 应用实例* @var \think\App*/protected $app;/*** 是否批量验证* @var bool*/protected $batchValidate = false;/*** 控制器中间件* @var array*/protected $middleware = [];/*** 构造方法* @access public* @param App $app 应用对象*/public function __construct(App $app) {$this->app = $app;$this->request = $this->app->request;// 控制器初始化$this->initialize();}// 初始化protected function initialize() {}/*** 验证数据* @access protected* @param array $data 数据* @param string|array $validate 验证器名或者验证规则数组* @param array $message 提示信息* @param bool $batch 是否批量验证* @return array|string|true* @throws ValidateException*/protected function validate(array $data, $validate, array $message = [], bool $batch = false) {if (is_array($validate)) {$v = new Validate();$v->rule($validate);} else {if (strpos($validate, '.')) {// 支持场景[$validate, $scene] = explode('.', $validate);}$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);$v = new $class();if (!empty($scene)) {$v->scene($scene);}}$v->message($message);// 是否批量验证if ($batch || $this->batchValidate) {$v->batch(true);}return $v->failException(true)->check($data);}}
一般文件位置(多应用,位置可以自定义,但是建议放到多应用目录下)
该控制器类的文件位置为:
app/home/BaseController.php
控制器后缀
如果你希望避免引入同名模型类的时候冲突,可以在route.php配置文件中设置
// 使用控制器后缀'controller_suffix' => true,
这样,上面的控制器类就需要改成
<?phpnamespace app\controller;class UserController{public function login(){return 'login';}}
相应的控制器类文件也要改为
app\controller\UserController.php
完整模板
控制器后缀&基础控制器&多应用模式&多级控制器
设定基础多应用为:home
目录结构
开启了控制器后缀,因此控制文件名后面要加入Controller,对应的类上面也加入Controller
app/home/BaseController.phpapp/home/user/LoginController.php
文件内容
文件:app/home/BaseController.php
<?phpdeclare(strict_types=1);namespace app\home;use think\App;use think\exception\ValidateException;use think\Validate;/*** 控制器基础类*/abstract class BaseController {/*** Request实例* @var \think\Request*/protected $request;/*** 应用实例* @var \think\App*/protected $app;/*** 是否批量验证* @var bool*/protected $batchValidate = false;/*** 控制器中间件* @var array*/protected $middleware = [];/*** 构造方法* @access public* @param App $app 应用对象*/public function __construct(App $app) {$this->app = $app;$this->request = $this->app->request;// 控制器初始化$this->initialize();}// 初始化protected function initialize() {}/*** 验证数据* @access protected* @param array $data 数据* @param string|array $validate 验证器名或者验证规则数组* @param array $message 提示信息* @param bool $batch 是否批量验证* @return array|string|true* @throws ValidateException*/protected function validate(array $data, $validate, array $message = [], bool $batch = false) {if (is_array($validate)) {$v = new Validate();$v->rule($validate);} else {if (strpos($validate, '.')) {// 支持场景[$validate, $scene] = explode('.', $validate);}$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);$v = new $class();if (!empty($scene)) {$v->scene($scene);}}$v->message($message);// 是否批量验证if ($batch || $this->batchValidate) {$v->batch(true);}return $v->failException(true)->check($data);}}
文件:app/home/user/LoginController.php
<?phpdeclare(strict_types=1);namespace app\home\controller\user;// 引入基础控制器命名空间use app\home\BaseController;class LoginController extends BaseController {public function index() {return "controller\user:Login@index";}}
访问URL
访问地址可以使用
http://serverName/home.php/user.login/index
定义路由访问
定义:
Route::get('user/login/index','user.login/index');
URL
http://serverName/home.php/user/login/index
空控制器(暂未理解)
空控制器的概念是指当系统找不到指定的控制器名称的时候,系统会尝试定位当前应用下的空控制器(Error)类,利用这个机制我们可以用来定制错误页面和进行URL的优化。
例如,下面是单应用模式下,我们可以给项目定义一个Error控制器类。
<?phpnamespace app\controller;class Error{public function __call($method, $args){return 'error request!';}}
