博客列表 >【ThinkPHP框架】多数据库配置、路由的使用、多应用设置等操作详解(附博客案例)

【ThinkPHP框架】多数据库配置、路由的使用、多应用设置等操作详解(附博客案例)

 一纸荒凉* Armani
 一纸荒凉* Armani原创
2021年05月29日 16:08:251908浏览

二十五、多库

我们可以在数据库配置文件中定义多个连接信息,配置多个数据库连接参数

1、配置数据库信息

注意:配置多库的时候,建议不要启用.env文件环境变量,不然数据库配置优先从当中获取数据,我们配置的多库信息将不起作用。

  1. 'connections' => [
  2. 'mysql' => [
  3. // 数据库类型
  4. 'type' => env('database.type', 'mysql'),
  5. // 服务器地址
  6. 'hostname' => env('database.hostname', '127.0.0.1'),
  7. // 数据库名
  8. 'database' => env('database.database', 'mydb'),
  9. // 用户名
  10. 'username' => env('database.username', 'root'),
  11. // 密码
  12. 'password' => env('database.password', 'root'),
  13. // 端口
  14. 'hostport' => env('database.hostport', '3306'),
  15. // 数据库连接参数
  16. 'params' => [],
  17. // 数据库编码默认采用utf8
  18. 'charset' => env('database.charset', 'utf8'),
  19. // 数据库表前缀
  20. 'prefix' => env('database.prefix', ''),
  21. // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
  22. 'deploy' => 0,
  23. // 数据库读写是否分离 主从式有效
  24. 'rw_separate' => false,
  25. // 读写分离后 主服务器数量
  26. 'master_num' => 1,
  27. // 指定从服务器序号
  28. 'slave_no' => '',
  29. // 是否严格检查字段是否存在
  30. 'fields_strict' => true,
  31. // 是否需要断线重连
  32. 'break_reconnect' => false,
  33. // 监听SQL
  34. 'trigger_sql' => env('app_debug', true),
  35. // 开启字段缓存
  36. 'fields_cache' => false,
  37. ],
  38. 'admin' => [
  39. // 数据库类型
  40. 'type' => env('database.type', 'mysql'),
  41. // 服务器地址
  42. 'hostname' => env('database.hostname', '127.0.0.1'),
  43. // 数据库名
  44. 'database' => env('database.database', 'admin'),
  45. // 用户名
  46. 'username' => env('database.username', 'root'),
  47. // 密码
  48. 'password' => env('database.password', 'root'),
  49. // 端口
  50. 'hostport' => env('database.hostport', '3306'),
  51. // 数据库连接参数
  52. 'params' => [],
  53. // 数据库编码默认采用utf8
  54. 'charset' => env('database.charset', 'utf8'),
  55. // 数据库表前缀
  56. 'prefix' => env('database.prefix', 'admin_'),
  57. // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
  58. 'deploy' => 0,
  59. // 数据库读写是否分离 主从式有效
  60. 'rw_separate' => false,
  61. // 读写分离后 主服务器数量
  62. 'master_num' => 1,
  63. // 指定从服务器序号
  64. 'slave_no' => '',
  65. // 是否严格检查字段是否存在
  66. 'fields_strict' => true,
  67. // 是否需要断线重连
  68. 'break_reconnect' => false,
  69. // 监听SQL
  70. 'trigger_sql' => env('app_debug', true),
  71. // 开启字段缓存
  72. 'fields_cache' => false,
  73. ]
  74. ],

2、创建用户表

新建数据库admin,添加admin_user表

  1. CREATE TABLE `admin_user` (
  2. `uid` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '管理员ID',
  3. `account` varchar(64) CHARACTER SET utf8 NOT NULL COMMENT '账号',
  4. `password` varchar(32) CHARACTER SET utf8 NOT NULL COMMENT '密码',
  5. `name` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '姓名',
  6. `times_login` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '登陆次数',
  7. `status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态 1开启 0禁用',
  8. `time_add` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
  9. `time_last` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最后登录时间',
  10. PRIMARY KEY (`uid`) USING BTREE
  11. ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='管理员表';
  12. INSERT INTO `admin_user` VALUES ('1', 'zhang', 'e10adc3949ba59abbe56e057f20f883e', '张帅', '10', '1', '1619159236', '1619159236');

3、controller 访问多库

我们可以调用 Db::connect 方法动态配置数据库连接信息,例如:

  1. namespace app\controller;
  2. use app\BaseController;
  3. use think\facade\Db;
  4. use think\facade\View;
  5. class Index extends BaseController{
  6. public function index(){
  7. $select = Db::connect('admin')->table('admin_user')->select();
  8. $select = Db::connect('admin')->name('user')->select();
  9. print_r($select);
  10. }
  11. }

connect 方法必须在查询的最开始调用,而且必须紧跟着调用查询方法,否则可能会导致部分查询失效或者依然使用默认的数据库连接。

4、model 访问多库

如果某个模型类里面定义了 connection 属性的话,则该模型操作的时候会自动按照给定的数据库配置进行 连接,而不是配置文件中设置的默认连接信息

  • 创建 model 文件:app/Model/AdminUser.php
  1. namespace app\model;
  2. use think\Model;
  3. class AdminUser extends Model{
  4. protected $connection = 'admin';
  5. protected $table = 'admin_user';
  6. protected $name = 'User';
  7. protected $pk = 'uid';
  8. public function get_data(){
  9. $select = static::select();
  10. return $select->toArray();
  11. }
  12. }

app\controller\Index.php 控制器

  1. namespace app\controller;
  2. use app\BaseController;
  3. use think\facade\Db;
  4. use think\facade\View;
  5. use app\model\User;
  6. class Index extends BaseController{
  7. public function index(){
  8. $db = new AdminUser();
  9. $index = $db->get_data();
  10. print_r($index);
  11. }
  12. }

二十六、路由

路由是应用开发中比较关键的一个环节,其主要作用包括但不限于:

  • 让URL更规范以及优雅;
  • 隐式传入额外请求参数;
  • 统一拦截并进行权限检查等操作;
  • 绑定请求数据;
  • 使用请求缓存;
  • 路由中间件支持;

路由定义文件

  • 要使用Route路由,必须在route\app.php文件引入 use think\facade\Route;

1、路由方法

  1. Route::rule('路由表达式', '路由地址', '请求类型');
  2. // 注册路由到News控制器的read操作
  3. Route::rule('new/:id','News/read');
  4. // 我们访问:http://zhang.com/new/5
  5. // 会自动路由到:http://zhang.com/News/read/id/5
  6. // 并且原来的访问地址会自动失效。
  7. // 请求类型不指定的话默认为任何请求类型有效
  8. Route::rule('new/:id', 'News/update', 'POST');
  9. Route::rule('new/:id','News/read','GET|POST');
  10. Route::快捷方法名('路由表达式', '路由地址');
  11. Route::get('new/<id>','News/read'); // 定义GET请求路由规则
  12. Route::post('new/<id>','News/update'); // 定义POST请求路由规则
  13. Route::put('new/:id','News/update'); // 定义PUT请求路由规则
  14. Route::delete('new/:id','News/delete'); // 定义DELETE请求路由规则
  15. Route::any('new/:id','News/read'); // 所有请求都支持的路由规则

2、配置路由

  1. use think\facade\Route;
  2. Route::rule('/', 'index');
  3. Route::rule('/', 'index/index');
  4. Route::rule('dlu', 'login/login');
  5. // 路由直接调用回调函数
  6. Route::get('think', function () {
  7. return 'hello,ThinkPHP6!';
  8. });
  9. // 路由到http://zhang.com/Code/index控制器方法
  10. Route::get('code', 'code/index');
  11. // 路由也可以携带参数跳转到对应控制器
  12. Route::get('hello/:name?', 'index/hello');
  13. Route::rule('/', 'index'); // 首页访问路由
  14. Route::rule('my', 'Member/myinfo'); // 静态地址路由
  15. Route::rule('blog/:id', 'Blog/read'); // 静态地址和动态地址结合
  16. Route::rule('new/:year/:month/:day', 'News/read'); // 静态地址和动态地址结合
  17. Route::rule(':user/:blog_id', 'Blog/read'); // 全动态地址

3、参数传值

  1. use think\facade\Route;
  2. // 必选参数 这两种传值都可以,但必须传值
  3. // http://zhang.com/hello?name=zhang
  4. // http://zhang.com/hello/zhang
  5. Route::rule('hello/:name', 'index/hello');
  6. Route::rule('hello/<name>', 'index/hello');
  7. // 可选参数,可以不传值,控制器方法中将按默认值输出
  8. Route::rule('hello/:name?', 'index/hello');
  9. Route::rule('hello/[:name]', 'index/hello');
  10. Route::rule('hello/<name?>', 'index/hello');

4、获取参数

  • 使用 Request 基类、门面类、助手函数都可以获取参数
  1. namespace app\controller;
  2. use app\BaseController;
  3. use think\facade\Request;
  4. class Login extends BaseController
  5. {
  6. public function login()
  7. {
  8. print_r(request()->param());
  9. print_r(Request::param());
  10. }
  11. }

5、参数可选

  1. use think\facade\Route;
  2. Route::rule('login/:id?', 'login/login');
  3. Route::rule('login/[:id]', 'login/login');
  4. Route::rule('login/<id?>', 'login/login');

6、完全匹配

在写路由地址的时候,发现写的路由前面的参数一样,后面无论添加什么,依然是访问前面的一个,这种情况就要用到路由完全匹配。

  1. use think\facade\Route;
  2. Route::rule('login/[:id]',function () {
  3. return 'hello,ThinkPHP6!';
  4. });
  5. Route::rule('login/admin/:id', function ($id) {
  6. return 'hello,'.$id;
  7. });
  8. Route::rule('login/:id$', 'login/login');
  9. Route::rule('login/<id>$', 'login/login');
  10. // 开启完全匹配
  11. Route::rule('login/<id>$', 'login/login')->completeMatch(true);

对象方式配置路由参数:https://www.kancloud.cn/manual/thinkphp6_0/1037499

  • 通过route.php配置路由参数 开启:完全匹配
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 路由设置
  4. // +----------------------------------------------------------------------
  5. return [
  6. // pathinfo分隔符
  7. 'pathinfo_depr' => '/',
  8. // URL伪静态后缀
  9. 'url_html_suffix' => 'html',
  10. // URL普通方式参数 用于自动生成
  11. 'url_common_param' => true,
  12. // 是否开启路由延迟解析
  13. 'url_lazy_route' => false,
  14. // 是否强制使用路由
  15. 'url_route_must' => false,
  16. // 合并路由规则
  17. 'route_rule_merge' => false,
  18. // 路由是否完全匹配
  19. 'route_complete_match' => false,
  20. // 访问控制器层名称
  21. 'controller_layer' => 'controller',
  22. // 空控制器名
  23. 'empty_controller' => 'Error',
  24. // 是否使用控制器后缀
  25. 'controller_suffix' => false,
  26. // 默认的路由变量规则
  27. 'default_route_pattern' => '[\w\.]+',
  28. // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
  29. 'request_cache_key' => false,
  30. // 请求缓存有效期
  31. 'request_cache_expire' => null,
  32. // 全局请求缓存排除规则
  33. 'request_cache_except' => [],
  34. // 默认控制器名
  35. 'default_controller' => 'Index',
  36. // 默认操作名
  37. 'default_action' => 'index',
  38. // 操作方法后缀
  39. 'action_suffix' => '',
  40. // 默认JSONP格式返回的处理方法
  41. 'default_jsonp_handler' => 'jsonpReturn',
  42. // 默认JSONP处理方法
  43. 'var_jsonp_handler' => 'callback',
  44. ];

7、额外参数

  • 隐式传值,URL 中看不到,起安全防护作用。如冲突,append 方法优先
  1. use think\facade\Route;Route::rule('login/<id>$', 'login/login')->append(['status' => 1, 'app_id' =>5]);

8、变量规则

变量规则:https://www.kancloud.cn/manual/thinkphp6_0/1037496

  • 配置参数:default_route_pattern
  • 系统默认的变量规则设置是\w+,只会匹配字母、数字、中文和下划线字符,并不会匹配特殊符号以及其它字符
  1. return [
  2. // pathinfo分隔符
  3. 'pathinfo_depr' => '/',
  4. // URL伪静态后缀
  5. 'url_html_suffix' => 'html',
  6. // URL普通方式参数 用于自动生成
  7. 'url_common_param' => true,
  8. // 是否开启路由延迟解析
  9. 'url_lazy_route' => false,
  10. // 是否强制使用路由
  11. 'url_route_must' => false,
  12. // 合并路由规则
  13. 'route_rule_merge' => false,
  14. // 路由是否完全匹配
  15. 'route_complete_match' => true,
  16. // 访问控制器层名称
  17. 'controller_layer' => 'controller',
  18. // 空控制器名
  19. 'empty_controller' => 'Error',
  20. // 是否使用控制器后缀
  21. 'controller_suffix' => false,
  22. // 默认的路由变量规则
  23. 'default_route_pattern' => '[\w\.]+',
  24. // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
  25. 'request_cache_key' => false,
  26. // 请求缓存有效期
  27. 'request_cache_expire' => null,
  28. // 全局请求缓存排除规则
  29. 'request_cache_except' => [],
  30. // 默认控制器名
  31. 'default_controller' => 'Index',
  32. // 默认操作名
  33. 'default_action' => 'index',
  34. // 操作方法后缀
  35. 'action_suffix' => '',
  36. // 默认JSONP格式返回的处理方法
  37. 'default_jsonp_handler' => 'jsonpReturn',
  38. // 默认JSONP处理方法
  39. 'var_jsonp_handler' => 'callback',
  40. ];
  • 局部变量规则
  1. use think\facade\Route;
  2. // pattern 方法作用:改变路由的传值规则,规则是用正则表达式
  3. // 路由传参的id只能为数字
  4. Route::rule('login/<id>$', 'login/login')->pattern(['id'=>'[0-9]+']);
  • 全局变量规则
  1. use think\facade\Route;
  2. Route::rule('login/<id>$', 'login/login');
  3. Route::pattern([
  4. 'id' => '\d+',
  5. ]);
  • 不需要开头添加 ^ 或者在最后添加 $,也不支持模式修饰符,系统会自动添加
  • $ ^ 修饰符:他们是正则表达式里的符号

9、分组路由

路由分组功能允许把相同前缀的路由定义合并分组,这样可以简化路由定义,并且提高路由匹配的效率,不必每次都去遍历完整的路由规则

路由分组:https://www.kancloud.cn/manual/thinkphp6_0/1037500

  1. use think\facade\Route;
  2. Route::group('blog', function () {
  3. Route::rule(':id', 'blog/read');
  4. Route::rule(':name', 'blog/read');
  5. })->ext('html')->pattern(['id' => '\d+', 'name' => '\w+']);
  6. Route::group('login', function () {
  7. Route::rule('l/<id>', 'login/login');
  8. Route::rule('r/<name>', 'login/reg');
  9. })->ext('html')->pattern(['id' => '\d+', 'name' => '\w+']);
  10. Route::group('/', function () {
  11. Route::rule('l/<id>', 'login/login');
  12. Route::rule('r/<name>', 'login/reg');
  13. });

  1. Route::group('blog', function () {
  2. Route::get('think/:id', function ($id='') {
  3. return 'blog/think'.$id;
  4. });
  5. // http://zhang.com/blog/think/6
  6. Route::get('php/:name?', function ($name='zhang') {
  7. return 'blog/php'.$name;
  8. });
  9. // http://zhang.com/blog/php/shuai
  10. Route::get('tp', function () {
  11. return 'thinkphp6';
  12. });
  13. // http://zhang.com/blog/tp
  14. });
  15. Route::group('blog', function () {
  16. Route::get('think/:id', function ($id='') {
  17. return 'blog/think'.$id;
  18. });
  19. // http://zhang.com/blog/think/6.html
  20. Route::get('php/:name?', function ($name='zhang') {
  21. return 'blog/php'.$name;
  22. });
  23. // http://zhang.com/blog/php/shuai.html
  24. Route::get('tp', function () {
  25. return 'thinkphp6';
  26. });
  27. // http://zhang.com/blog/tp.html
  28. })->ext('html|php');
  29. // URL后缀检测,支持匹配多个后缀
  30. // 如果ext方法不传入任何值,表示不允许使用任何后缀访问。

10、路由参数

路由分组及规则定义支持指定路由参数,这些参数主要完成路由匹配检测以及后续行为。

https://www.kancloud.cn/manual/thinkphp6_0/1037499

路由参数可以在定义路由规则的时候直接传入(批量),推荐使用方法配置更加清晰。

参数 说明 方法名
ext URL后缀检测,支持匹配多个后缀 ext
deny_ext URL禁止后缀检测,支持匹配多个后缀 denyExt
https 检测是否https请求 https
domain 域名检测 domain
complete_match 是否完整匹配路由 completeMatch
model 绑定模型 model
cache 请求缓存 cache
ajax Ajax检测 ajax
pjax Pjax检测 pjax
json JSON检测 json
validate 绑定验证器类进行数据验证 validate
append 追加额外的参数 append
middleware 注册路由中间件 middleware
filter 请求变量过滤 filter

二十七、多应用

  • 一个项目中往往要有前台index应用和后台admin应用以及更多,这时候就要开启多应用模式。
  • 如果要使用多应用模式,你需要安装多应用模式扩展 think-multi-app
  • composer require topthink/think-multi-app
  • 通过php think build 应用名命令创建多应用目录文件夹,也可以手动新建应用文件夹和其中的MVC文件
  • 一般需要单独配置应用时需要从项目根目录把主文件下的config配置文件和route配置文件复制到应用目录下就可以单独设置应用配置
  • 通过命令php think make:controller admin@Index --plain来命令创建控制器(其中—plain是否生成函数)

多应用模式:https://www.kancloud.cn/manual/thinkphp6_0/1297876

http://zhang.com ===> http://zhang.com/index/index/index

如果直接访问域名根目录,访问的其实是index默认应用,可以通过app.php配置文件的default_app配置参数指定默认应用。

1、目录结构

  1. ├─app 应用目录
  2. ├─index 主应用
  3. ├─controller 控制器目录
  4. ├─model 模型目录
  5. ├─view 视图目录
  6. ├─config 配置目录
  7. ├─route 路由目录
  8. └─ ... 更多类库目录
  9. ├─admin 后台应用
  10. ├─controller 控制器目录
  11. ├─model 模型目录
  12. ├─view 视图目录
  13. ├─config 配置目录
  14. ├─route 路由目录
  15. └─ ... 更多类库目录
  16. ├─AppService.php 应用服务类
  17. ├─BaseController.php 默认基础控制器类
  18. ├─common.php 全局公共函数文件
  19. ├─event.php 全局事件定义文件
  20. ├─ExceptionHandle.php 应用异常定义文件
  21. ├─middleware.php 全局中间件定义文件
  22. ├─provider.php 服务提供定义文件
  23. ├─Request.php 应用请求对象
  24. └─service.php 系统服务定义文件

2、创建目录

  • 创建 app/index 应用目录
  • 把之前的MVC 目录放到刚创建的index应用目录中
  1. namespace app\index\controller;
  2. use app\BaseController;
  3. use think\facade\Db;
  4. use think\facade\View;
  5. use think\facade\Request;
  6. class Index extends BaseController{
  7. public function index(){
  8. $cat = Db::table('cat')->select();
  9. $c = input('get.c',0);
  10. $t = input('get.t','');
  11. $where[] = ['status','=',1];
  12. if($c != 0){
  13. $where[] = ['cat','=',$c];
  14. }else if(!empty($t)){
  15. $where[] = ['title','like','%'.$t.'%'];
  16. }
  17. $select = Db::table('boke')->where($where)->paginate(10);
  18. $page = $select->render();
  19. echo $select->total();
  20. View::assign([
  21. 'c' => $c,
  22. 't' => $t,
  23. 'cat' => $cat,
  24. 'select' => $select,
  25. 'page' => $page
  26. ]);
  27. return View::fetch('index');
  28. }
  29. }

3、访问路径

单应用:http://zhang.com/index.php/控制器名称/操作方法/参数

多应用:http://zhang.com/index.php/应用名称/控制器名称/操作方法/参数

完整路径:http://zhang.com/index.php/index/index/index

4、创建多项目

  • 创建 app/admin应用 目录
  • 创建 MVC 目录在admin应用目录下
  • 创建 Index.php 控制器
  1. namespace app\admin\controller;
  2. use app\BaseController;
  3. use think\facade\Db;
  4. use think\facade\View;
  5. use think\facade\Request;
  6. class Index extends BaseController
  7. {
  8. public function index(){
  9. return View::fetch();
  10. }
  11. }

5、数据库配置

  • 创建 app/index/config/database.php 文件
  1. return [
  2. // 默认使用的数据库连接配置
  3. 'default' => env('database.driver', 'mysql'),
  4. // 自定义时间查询规则
  5. 'time_query_rule' => [],
  6. // 自动写入时间戳字段
  7. // true为自动识别类型 false关闭
  8. // 字符串则明确指定时间字段类型 支持 int timestamp datetime date
  9. 'auto_timestamp' => true,
  10. // 时间字段取出后的默认时间格式
  11. 'datetime_format' => 'Y-m-d H:i:s',
  12. // 数据库连接配置信息
  13. 'connections' => [
  14. 'mysql' => [
  15. // 数据库类型
  16. 'type' => env('database.type', 'mysql'),
  17. // 服务器地址
  18. 'hostname' => env('database.hostname', '127.0.0.1'),
  19. // 数据库名
  20. 'database' => env('database.database', 'oyk'),
  21. // 用户名
  22. 'username' => env('database.username', 'root'),
  23. // 密码
  24. 'password' => env('database.password', 'root'),
  25. // 端口
  26. 'hostport' => env('database.hostport', '3306'),
  27. // 数据库连接参数
  28. 'params' => [],
  29. // 数据库编码默认采用utf8
  30. 'charset' => env('database.charset', 'utf8'),
  31. // 数据库表前缀
  32. 'prefix' => env('database.prefix', ''),
  33. // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
  34. 'deploy' => 0,
  35. // 数据库读写是否分离 主从式有效
  36. 'rw_separate' => false,
  37. // 读写分离后 主服务器数量
  38. 'master_num' => 1,
  39. // 指定从服务器序号
  40. 'slave_no' => '',
  41. // 是否严格检查字段是否存在
  42. 'fields_strict' => true,
  43. // 是否需要断线重连
  44. 'break_reconnect' => false,
  45. // 监听SQL
  46. 'trigger_sql' => env('app_debug', true),
  47. // 开启字段缓存
  48. 'fields_cache' => false,
  49. ],
  50. 'admin' => [
  51. // 数据库类型
  52. 'type' => env('database.type', 'mysql'),
  53. // 服务器地址
  54. 'hostname' => env('database.hostname', '127.0.0.1'),
  55. // 数据库名
  56. 'database' => env('database.database', 'admin'),
  57. // 用户名
  58. 'username' => env('database.username', 'root'),
  59. // 密码
  60. 'password' => env('database.password', 'root'),
  61. // 端口
  62. 'hostport' => env('database.hostport', '3306'),
  63. // 数据库连接参数
  64. 'params' => [],
  65. // 数据库编码默认采用utf8
  66. 'charset' => env('database.charset', 'utf8'),
  67. // 数据库表前缀
  68. 'prefix' => env('database.prefix', ''),
  69. // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
  70. 'deploy' => 0,
  71. // 数据库读写是否分离 主从式有效
  72. 'rw_separate' => false,
  73. // 读写分离后 主服务器数量
  74. 'master_num' => 1,
  75. // 指定从服务器序号
  76. 'slave_no' => '',
  77. // 是否严格检查字段是否存在
  78. 'fields_strict' => true,
  79. // 是否需要断线重连
  80. 'break_reconnect' => false,
  81. // 监听SQL
  82. 'trigger_sql' => env('app_debug', true),
  83. // 开启字段缓存
  84. 'fields_cache' => false,
  85. ]
  86. // 更多的数据库配置信息
  87. ],
  88. ];

6、路由配置

  • 创建 app/index/route/app.php 文件
  1. use think\facade\Route;
  2. Route::group('/', function () {
  3. Route::rule('login/<id>', 'login/login');
  4. Route::rule('reg/<name>', 'login/reg');
  5. });

ThinkPHP6 博客实战


博客数据库

boke.sql

  1. SET FOREIGN_KEY_CHECKS=0;
  2. -- ----------------------------
  3. -- Table structure for boke
  4. -- ----------------------------
  5. DROP TABLE IF EXISTS `boke`;
  6. CREATE TABLE `boke` (
  7. `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  8. `title` varchar(300) DEFAULT NULL COMMENT '标题',
  9. `img` varchar(300) DEFAULT NULL COMMENT '图片',
  10. `content` text COMMENT '内容',
  11. `date` date DEFAULT NULL COMMENT '时间',
  12. `cat` varchar(50) DEFAULT NULL COMMENT '类型',
  13. `num` int(10) unsigned DEFAULT '0' COMMENT '浏览量',
  14. `hot` tinyint(1) unsigned DEFAULT '0' COMMENT '热门 1是 0否',
  15. `status` tinyint(1) unsigned DEFAULT '1' COMMENT '状态 1开启 0关闭',
  16. PRIMARY KEY (`id`)
  17. ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
  18. -- ----------------------------
  19. -- Records of boke
  20. -- ----------------------------
  21. INSERT INTO `boke` VALUES ('1', '《天龙八部》系列课程整理', 'https://img.php.cn/upload/course/000/000/001/5d242759adb88970.jpg', 'PHP中文网因专业的讲师水平和高效的视频质量,推出的各种视频课程系列一直以来都深受大家喜爱。特别是《天龙八部》系列、《独孤九贱》系列、《玉女心经》系列的原创课程在行业内更是具有强大的影响力,好评不断!为了让大家能更快速方便的寻找到相关教程资源,我们在这篇文章中特意将《天龙八部》系列课程整理出来供大家有针对性得学习!', '2021-02-18', '2', '0', '0', '1');
  22. INSERT INTO `boke` VALUES ('2', 'php中文网《玉女心经》公益PHP WEB培训系列课程汇总', 'https://img.php.cn/upload/course/000/126/153/5aa23f0ded921649.jpg', 'php中文网近期推出的《独孤九贱》系列、《天龙八部》系列、《玉女心经》原创视频课程,好评如潮!由于《玉女心经》系列课程没有做成专题,所以大家找起来有点费劲,为了更好的服务广大php中文网粉丝们,特把课程整理汇总给大家!', '2021-02-11', '2', '0', '0', '1');
  23. INSERT INTO `boke` VALUES ('3', 'html5中submit是按钮么', null, 'html5中submit是按钮,它是button的一个特例,它把提交这个动作自动集成了。submit会自动将表单的数据提交,使用submit时需要验证要加return', '2021-02-10', '4', '0', '0', '1');
  24. INSERT INTO `boke` VALUES ('4', 'css如何去除下划线', null, 'css去除下划线的方法:首先创建一个HTML示例文件;然后在body中定义一个a标签;最后通过css属性为“a{text-decoration:none}”去除下划线即可。', '2021-02-01', '4', '0', '0', '1');
  25. INSERT INTO `boke` VALUES ('5', 'linux如何查看进程', 'https://img.php.cn/upload/article/202102/24/2021022409272725770.jpg', 'windows defender是windows系统自带的一款杀毒软件,对于很多人来说,这款软件不仅没有起到保护电脑的作用,还增加了很多不必要的麻烦。比如我们安装了一些破解版软件,windows defender就会杀这些破解软件,很让人讨厌。', '2021-02-01', '6', '1', '0', '1');
  26. INSERT INTO `boke` VALUES ('6', 'Ubuntu20.04/18.04下安装或更新至PHP8', 'https://img.php.cn/upload/article/000/000/020/2c02ff679ec7afab974a691aac09d535-0.png', '本指南让你了解如何安装最新的 php 版本 8,并在你的任何 VPS、云服务器、专用主机上的 Ubuntu 20.0 或 18.04 系统中升级到最新版本,并将其配置为 Apache 和 Nginx。', '2021-02-01', '2', '5', '0', '0');
  27. INSERT INTO `boke` VALUES ('7', 'PHP 8新特性之JIT对PHP应用性能的影响', null, '即将发布的 PHP 8 最受大家关注的新特性就是引入了对 JIT 的支持,我已经简单介绍了 JIT 是什么,以及与 Opcache 的区别', '2021-02-01', '2', '97', '0', '1');
  28. INSERT INTO `boke` VALUES ('8', '详解PHP7中的zval结构和引用计数机制', 'https://img.php.cn/upload/article/000/000/024/6053286f637d2966.jpg', '最近在查阅 PHP7 垃圾回收的资料的时候,网上的一些代码示例在本地环境下运行时出现了不同的结果,使我一度非常迷惑。 仔细一想不难发现问题所在:这些文章大多是 PHP5.x 时代的,而 PHP7 发布后,采用了新的 zval 结构,相关的资料也比较贫瘠,所以我结合一些资料做了一个总结,主要侧重于解释新 zval 容器中的引用计数机制,如有谬误,还望不吝指教。', '2021-01-01', '2', '185', '0', '1');
  29. INSERT INTO `boke` VALUES ('9', 'php登录失败怎么处理', 'https://img.php.cn/upload/article/202103/19/2021031909102812621.jpg', 'php登录失败的处理方法:首先创建一个表负责记录用户登录的信息;然后从user_login_info表查询最近30分钟内有没有相关密码错误的记录;接着统计记录总条数是否达到设定的错误次数;最后设置登录密码错误次数限制即可。', '2021-01-01', '2', '0', '0', '1');
  30. INSERT INTO `boke` VALUES ('10', 'php如何去掉字符串末尾字符', 'https://img.php.cn/upload/article/000/000/024/6053250623ecf930.jpg', 'php去掉字符串末尾字符的方法:1、直接使用substr()函数倒序裁掉最后一位字符,语法“substr(string,0,-1)”;2、使用rtrim()函数,语法“rtrim(string,charlist)”。', '2021-01-01', '2', '0', '0', '1');
  31. INSERT INTO `boke` VALUES ('11', 'php异常和错误的区别是什么', 'https://img.php.cn/upload/article/202103/18/2021031817511956954.jpg', 'php异常和错误的区别:1、PHP错误是属于php程序自身的问题,一般是由非法的语法,环境问题导致的;2、PHP异常一般是业务逻辑上出现的不合预期、与正常流程不同的状况,不是语法错误。', '2021-01-01', '2', '0', '0', '1');
  32. INSERT INTO `boke` VALUES ('12', 'linux下如何查看php-fpm是否安装', 'https://img.php.cn/upload/article/000/000/024/60532042dd48f908.jpg', 'linux下查看php-fpm是否安装的方法:打开终端,执行“whereis php-fpm”或者“find / -name php-fpm”命令,如果成功输出php-fpm的安装位置,则表示有安装。', '2021-01-01', '2', '0', '0', '1');
  33. INSERT INTO `boke` VALUES ('13', 'php的数据库修改语句是什么', 'https://img.php.cn/upload/article/202103/18/2021031817353472746.jpg', 'php的数据库修改语句是UPDATE,用于更新数据库表中已存在的记录,语法为【UPDATE table_name SET column1=value, column2=value2,...WHERE some_column=some 】。', '2021-01-01', '2', '0', '0', '1');
  34. INSERT INTO `boke` VALUES ('14', 'php怎么设置状态码', 'https://img.php.cn/upload/article/000/000/024/60531da39e7a2975.jpg', '在php中,可以使用http_response_code()函数来设置状态码,该函数用于设置响应的HTTP状态码,语法格式“http_response_code (状态码) ”。', '2021-01-01', '2', '0', '0', '1');
  35. INSERT INTO `boke` VALUES ('15', 'excel怎么冻结选定区域', 'https://img.php.cn/upload/article/202103/18/2021031817270344979.jpg', 'excel冻结选定区域的方法:首先选定你想固定不变的位置;然后点击表格最上面的菜单栏“视图”那里,再点击“冻结窗格”下方的“冻结窗格”即可。', '2021-01-01', '2', '0', '0', '1');
  36. INSERT INTO `boke` VALUES ('16', '在线考试系统实战【公益直播】', 'https://img.php.cn/upload/course/000/000/001/60862c6ba99af257.png', '三天大型公益直播课《模仿驾校考试系统实战开发》,使用框架: bootstrap、jquery、ThinkPHP6.0', '2021-05-06', '2', '0', '0', '1');

cat.sql

  1. SET FOREIGN_KEY_CHECKS=0;
  2. -- ----------------------------
  3. -- Table structure for cat
  4. -- ----------------------------
  5. DROP TABLE IF EXISTS `cat`;
  6. CREATE TABLE `cat` (
  7. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  8. `name` varchar(50) NOT NULL COMMENT '分类名',
  9. `sort` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '排序',
  10. `status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态 1开启 0关闭',
  11. PRIMARY KEY (`id`)
  12. ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
  13. -- ----------------------------
  14. -- Records of cat
  15. -- ----------------------------
  16. INSERT INTO `cat` VALUES ('1', 'Layui', '0', '1');
  17. INSERT INTO `cat` VALUES ('2', 'PHP', '2', '1');
  18. INSERT INTO `cat` VALUES ('3', 'ThinkPHP', '0', '1');
  19. INSERT INTO `cat` VALUES ('4', '前端', '0', '1');
  20. INSERT INTO `cat` VALUES ('5', '小程序', '0', '1');
  21. INSERT INTO `cat` VALUES ('6', '服务器', '0', '1');

一、控制器

  • 新建 Base.php 文件
  1. namespace app\index\controller;
  2. use app\BaseController;
  3. use app\AppApi;
  4. use think\facade\Db;
  5. use think\facade\View;
  6. class Base extends BaseController{
  7. public function __construct(){
  8. $cat = Db::table('cat')->select();
  9. $hot = Db::table('boke')->where('status',1)->where('hot',1)->limit(10)->select();
  10. View::assign([
  11. 'cat' => $cat,
  12. 'hot' => $hot
  13. ]);
  14. }
  15. }
  • Index.php 文件
  1. namespace app\index\controller;
  2. use app\index\controller\Base;
  3. use think\facade\Db;
  4. use think\facade\View;
  5. use think\facade\Request;
  6. class Index extends Base
  7. {
  8. public function index(){
  9. $select = Db::table('boke a')->join(['cat'=>'c'],'a.cat=c.id')->where('a.status',1)->limit(10)->order('a.bid DESC')->select();
  10. View::assign([
  11. 'select' => $select
  12. ]);
  13. return View::fetch();
  14. }
  15. public function lists(){
  16. $c = Request::param('c',0);
  17. $t = Request::param('t','');
  18. $where[] = ['a.status','=',1];
  19. if($c != 0){
  20. $where[] = ['a.cat','=',$c];
  21. }else if(!empty($t)){
  22. $where[] = ['a.title','like','%'.$t.'%'];
  23. }
  24. $select = Db::table('boke a')->join(['cat'=>'c'],'a.cat=c.id')->where($where)->order('a.bid DESC')->paginate(10);
  25. $page = $select->render();
  26. View::assign([
  27. 't' => $t,
  28. 'select' => $select,
  29. 'page' => $page
  30. ]);
  31. return View::fetch();
  32. }
  33. public function details(){
  34. $id = Request::param('id');
  35. $find = Db::table('boke')->where('bid',$id)->find();
  36. if(!empty($find)){
  37. $class = Db::table('cat')->where('id',$find['cat'])->find();
  38. }
  39. View::assign([
  40. 'find' => $find,
  41. 'class' => $class
  42. ]);
  43. return View::fetch();
  44. }
  45. }

二、视图

  • Index/index.html
  1. {include file="public/head" /}
  2. <div id="main" class="wrapper">
  3. <div id="primary" class="site-content">
  4. {foreach($select as $select_v)}
  5. <div id="content" role="main">
  6. <article>
  7. <header class="entry-header">
  8. <h1 class="entry-title"><a href="/index/d/{$select_v['bid']}" title="{$select_v['title']}" rel="bookmark">{$select_v['title']}</a></h1>
  9. </header>
  10. <div class="entry-content">{$select_v['title']}</div>
  11. <footer class="entry-meta">
  12. 发布于
  13. <a href="/index/d/{$select_v['bid']}" title="{$select_v['date']}" rel="bookmark">
  14. <time class="entry-date" datetime="{$select_v['date']}">{$select_v['date']}</time>
  15. </a>。 属于
  16. <a href="/index/l/{$select_v['cat']}" title="查看 {$select_v['name']}中的全部文章" rel="category">{$select_v['name']}</a> 分类
  17. </footer>
  18. </article>
  19. </div>
  20. {/foreach}
  21. </div>
  22. {include file="public/tail" /}
  • Index/lists.html
  1. {include file="public/head" /}
  2. <div id="main" class="wrapper">
  3. <div id="primary" class="site-content">
  4. {foreach($select as $select_v)}
  5. <div id="content" role="main">
  6. <article>
  7. <header class="entry-header">
  8. <h1 class="entry-title"><a href="/index/d/{$select_v['bid']}" title="{$select_v['title']}" rel="bookmark">{$select_v['title']}</a></h1>
  9. </header>
  10. <div class="entry-content">{$select_v['title']}</div>
  11. <footer class="entry-meta">
  12. 发布于
  13. <a href="/index/d/{$select_v['bid']}" title="{$select_v['date']}" rel="bookmark">
  14. <time class="entry-date" datetime="{$select_v['date']}">{$select_v['date']}</time>
  15. </a>。 属于
  16. <a href="/index/l/{$select_v['cat']}" title="查看 {$select_v['name']}中的全部文章" rel="category">{$select_v['name']}</a> 分类
  17. </footer>
  18. </article>
  19. </div>
  20. {/foreach}
  21. <div class="page">
  22. <nav>
  23. <ul class="pagination">
  24. {$select|raw}
  25. </ul>
  26. </nav>
  27. </div>
  28. </div>
  29. {include file="public/tail" /}
  • Index/details.html
  1. {include file="public/head" /}
  2. <div id="main" class="wrapper">
  3. <div id="primary" class="site-content">
  4. <div id="content" role="main">
  5. <article>
  6. <header class="entry-header">
  7. <h1 class="entry-title">
  8. {$find['title']}
  9. </h1>
  10. </header>
  11. <div class="entry-content ql-editor" id="md-editor" style="padding: 0;">
  12. {$find['content']}
  13. </div>
  14. <footer class="entry-meta">
  15. 发布于
  16. <a href="" title="{$find['date']}" rel="bookmark">
  17. <time class="entry-date" datetime="{$find['date']}">{$find['date']}</time>
  18. </a>。 属于
  19. <a href="/index.html?cate=4" title="查看 {$class['name']}中的全部文章" rel="category">{$class['name']}</a> 分类
  20. </footer>
  21. </article>
  22. </div>
  23. </div>
  24. {include file="public/tail" /}
  • public/head.html
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>首页 - 欧阳克个人博客</title>
  6. <meta name="keywords" content="博客,个人博客,欧阳克个人博客,PHP"/>
  7. <meta name="description" content="欧阳克是PHP中文网的讲师,愿意把知识分享给大家。" />
  8. <link rel="stylesheet" id="twentytwelve-style-css" href="/static/css/index.css" type="text/css" media="all" />
  9. <style type="text/css" id="custom-background-css">
  10. body.custom-background {background-color:#e6e6e6;}
  11. input.btn-default:focus,input.no-border:focus {outline:none;}
  12. input.no-border {font-size:15px;}
  13. </style>
  14. <script type="text/javascript" src="/static/js/jquery.js"></script>
  15. <script type="text/javascript" src="/static/js/nav.js"></script>
  16. </head>
  17. <body class="home blog custom-background custom-font-enabled single-author">
  18. <div id="page" class="hfeed site">
  19. <header id="masthead" class="site-header" role="banner">
  20. <hgroup>
  21. <h1 class="site-title">
  22. <a href="/" title="欧阳克个人博客" rel="home">欧阳克个人博客</a>
  23. </h1>
  24. <h2 class="site-description">欧阳克是PHP中文网的讲师,愿意把知识分享给大家。</h2>
  25. </hgroup>
  26. <nav id="site-navigation" class="main-navigation" role="navigation">
  27. <ul class="nav-menu">
  28. <li>
  29. <a href="/">首页</a>
  30. </li>
  31. {if($cat)}
  32. {foreach $cat as $cat_v}
  33. <li>
  34. <a href="/index/l/{$cat_v['id']}">{$cat_v['name']}</a>
  35. </li>
  36. {/foreach}
  37. {/if}
  38. </ul>
  39. </nav>
  40. </header>
  • public/tail.html
  1. <div id="secondary" class="widget-area" role="complementary">
  2. <aside id="search-2" class="widget widget_search">
  3. <form role="search" action="/index/l" method="GET">
  4. <div>
  5. <label class="screen-reader-text" for="t">搜索:</label>
  6. <input placeholder="搜索" type="text" class="no-border" name="t" id="t" value="" />
  7. <input type="submit" class="btn btn-default" value="搜索" />
  8. </div>
  9. </form>
  10. </aside>
  11. {if(!empty($hot))}
  12. <aside id="recent-posts-2" class="widget widget_recent_entries">
  13. <h3 class="widget-title">热门文章</h3>
  14. <ul>
  15. {volist name="hot" id="hot_v" key="k"}
  16. <li>
  17. <font style="color:#7a7a7a;">[{$k}]</font>&nbsp;
  18. <a href="/index/d/{$hot_v['bid']}" title="{$hot_v['title']}">{$hot_v['title']}</a>
  19. </li>
  20. {/volist}
  21. </ul>
  22. </aside>
  23. {/if}
  24. </div>
  25. </div>
  26. <footer id="colophon" role="contentinfo">
  27. <div class="site-info">
  28. <span>友情链接:</span>
  29. <a href="https://www.php.cn" target="_blank">PHP中文网</a>
  30. </div>
  31. </footer>
  32. <footer role="contentinfo" style="margin-top:0;">
  33. <div class="site-info" style="text-align:center;">
  34. <span>
  35. <a href="https://beian.miit.gov.cn" target="_blank">苏ICP备2020058653号-1</a>
  36. </span>
  37. </div>
  38. </footer>
  39. </div>
  40. </body>
  41. </html>

三、配置

  • route/app.php 路由配置
  1. use think\facade\Route;
  2. Route::rule('/', 'index/index');
  3. Route::rule('list/[:c]/[:t]', 'index/lists');
  4. Route::rule('article/:id', 'index/details');
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议