控制器定义

  • 控制器文件通常放在 application/module/controller下面,类名和文件名保持大小写一致,并采用驼峰命名(首字母大写)。
  • 为了更方便使用,控制器类建议继承系统的控制器基类think\Controller,虽然无需继承也可以使用

例如:现在定一个控制器 HelloWorld , 它的实际位置:application\test\controller\HelloWorld.php

  1. <?php
  2. namespace app\test\controller;
  3. use think\Controller;
  4. class HelloWorld extends Controller
  5. {
  6. public function helloWorld()
  7. {
  8. return 'Hello World';
  9. }
  10. }

现在我不定义路由规则去访问:
image.png

关闭URL的自动转换设置后:config\app.php 下,将默认的 true 改为 false

  1. <?php
  2. // 是否自动转换URL中的控制器和操作名
  3. 'url_convert' => false,

现在就可以使用 tp5.1.com/test/HelloWorld/helloworld 来进行访问了。
image.png


控制器命名空间

控制器类的所在命名空间为app\module\controller,其中根命名空间app为系统默认,并且只能通过环境变量设置更改,例如我们可以在.env配置文件中设置:

  1. <?php
  2. APP_NAMESPACE = application

则实际的控制器类应该更改定义如下:

  1. <?php
  2. namespace application\index\controller;
  3. class Index
  4. {
  5. public function index()
  6. {
  7. return 'index';
  8. }
  9. }

上面这些都是手册说明的,下面演示一遍。

我在项目根目录下创建一个 .env 文件(找是找不到的)。写入 APP_NAMESPACE = application
image.png

改变 namespace Line4

  1. <?php
  2. namespace application\test\controller;
  3. use think\Controller;
  4. class HelloWorld extends Controller
  5. {
  6. public function helloWorld()
  7. {
  8. return 'Hello World';
  9. }
  10. }

postman 测试:
image.png


单一模块控制器

类比 laravel 的单行为控制器

在应用配置文件app.php中设置

  1. <?php
  2. // 是否支持多模块
  3. 'app_multi_module' => false,

可以启用单一模块,那么控制器的命名空间中不需要模块名了,类的定义就变成了

  1. <?php
  2. namespace app\controller;
  3. class Index
  4. {
  5. public function index()
  6. {
  7. return 'index';
  8. }
  9. }

控制器类文件的实际位置则变成

  1. <?php
  2. application\controller\Index.php

渲染输出

默认情况下,控制器的输出全部采用return的方式,无需进行任何的手动输出,系统会自动完成渲染内容的输出。下面都是有效的输出方式:

控制器:application\test\controller\Index.php

  1. <?php
  2. namespace app\test\controller;
  3. class Index
  4. {
  5. public function hello()
  6. {
  7. // 输出hello,world!
  8. return 'hello,world!';
  9. }
  10. public function json()
  11. {
  12. // 输出JSON
  13. $data = [
  14. 'name' => 'xs',
  15. 'age' => 24,
  16. 'sex' => 'male'
  17. ];
  18. return json($data);
  19. }
  20. public function read()
  21. {
  22. // 渲染默认模板输出
  23. return view('test@goods');
  24. }
  25. }

postman 测试:

第一种方式:return 字符串
image.png

第二种方式:return JSON
image.png

第三种方式:return view 视图,注意路径问题。
image.png

我这里实际上定义的 view 文件的结构是这样的
image.png

这样写的话,它强制要求我必须,在模块的 view 下继续分级,而分级的这个标准就是 控制器的名称。如果我们不想这么做,也是可以的。直接在 view 下使用 一级文件。
image.png

控制器:我们这样写就好了,直接使用绝对路径就行了。

  1. <?php
  2. public function read()
  3. {
  4. // 渲染默认模板输出
  5. return view('../application/test/view/goods.html');
  6. }

postman 访问测试:
image.png


输出装换

默认情况下,控制器的返回输出不会做任何的数据处理,但可以设置输出格式,并进行自动的数据转换处理,前提是控制器的输出数据必须采用return的方式返回。

不设置:

  1. <?php
  2. public function test1()
  3. {
  4. return [
  5. 'name' => 'xs',
  6. 'age' => 24
  7. ];
  8. }

postman 查看:会查看直接报错。tp5.1 我们不能直在控制层返回数组。可是使用 json() 方法转将数组转成 JSON字符串,也可已修改 返回的数据类型。
image.png

修改返回的数组类型:config\app.php 中进行设置 Line 31,默认是 html

  1. <?php
  2. // 默认输出类型
  3. 'default_return_type' => 'json',

再次访问:会发现返回的数据类型被自动改成了 json
image.png


多级控制器 (了解)

支持任意层次级别的控制器,并且支持路由,例如:

  1. <?php
  2. namespace app\index\controller\user;
  3. use think\Controller;
  4. class Blog extends Controller
  5. {
  6. public function index()
  7. {
  8. return 'index';
  9. }
  10. }

该控制器类的文件位置为:

  1. <?php
  2. application/index/controller/user/Blog.php

访问地址可以使用

  1. <?php
  2. http://serverName/index.php/index/user.blog/index

由于URL访问不能访问默认的多级控制器(可能会把多级控制器名误识别为URL后缀),因此建议所有的多级控制器都通过路由定义后访问,如果要在路由定义中使用多级控制器,可以使用:

  1. <?php
  2. \think\Route::get('user/blog','index/user.blog/index');

自动定位控制器 (了解)

如果你使用了多级控制器的话,可以设置controller_auto_search参数开启自动定位控制器,便于URL访问,首先在应用配置文件中设置:

  1. <?php
  2. 'controller_auto_search' => true,

然后定义控制器如下:

  1. <?php
  2. namespace app\index\controller\user;
  3. use think\Controller;
  4. class Blog extends Controller
  5. {
  6. public function index()
  7. {
  8. return 'index';
  9. }
  10. }

我们就可以直接访问下面的URL地址了:

  1. <?php
  2. http://serverName/index.php/index/user/Blog

控制器初始化 (了解)

如果你的控制器类继承了系统控制器基类(\think\Controller)的话,可以定义控制器初始化方法initialize,该方法会在调用控制器的方法之前首先执行,如非必要,不建议直接修改控制器的架构函数。
例如:

  1. <?php
  2. namespace app\index\controller;
  3. use think\Controller;
  4. class Index extends Controller
  5. {
  6. protected function initialize()
  7. {
  8. echo 'init<br/>';
  9. }
  10. public function hello()
  11. {
  12. return 'hello';
  13. }
  14. public function data()
  15. {
  16. return 'data';
  17. }
  18. }

initialize方法不需要任何返回值

如果访问

  1. http://localhost/index.php/index/Index/hello

会输出

  1. init
  2. hello

如果访问

  1. http://localhost/index.php/index/Index/data

会输出

  1. init
  2. data