路由

隐藏index.php文件

默认的写法是 :[@]模块名/控制器名/方法名
image.png
那么匹配的路径就是:http://127.0.0.1/public/index.php/xx/index/dd

之前全路径是:http://127.0.0.1/public/index.php/index/index/index
现在想: http://127.0.0.1/public/index/index/index

1、打开apache重写模块

httpd.conf 文件
LoadModule rewrite_module modules/mod_rewrite.so
图片1.png

2、配置虚拟主机中允许重写

D:\devtool\phpstudy_pro\Extensions\Apache2.4.39\conf\vhosts\tkphp.com_80.conf
image.png

  1. <VirtualHost *:80>
  2. DocumentRoot "D:/devtool/phpstudy_pro/WWW/tp5.1"
  3. ServerName tkphp.com
  4. ServerAlias
  5. FcgidInitialEnv PHPRC "D:/devtool/phpstudy_pro/Extensions/php/php7.3.4nts"
  6. AddHandler fcgid-script .php
  7. FcgidWrapper "D:/devtool/phpstudy_pro/Extensions/php/php7.3.4nts/php-cgi.exe" .php
  8. <Directory "D:/devtool/phpstudy_pro/WWW/tp5.1">
  9. Options FollowSymLinks ExecCGI
  10. # 是否允许使用.htaccess文件
  11. AllowOverride All
  12. # 访问目录权限
  13. Require all granted
  14. DirectoryIndex index.php index.html error/index.html
  15. </Directory>
  16. </VirtualHost>

3、在入口文件中要有.htaccess文件

注意目录!!!是public下的.htaccess文件
image.png
二选一。总有一个是对的。

  1. <IfModule mod_rewrite.c>
  2. Options +FollowSymlinks -Multiviews
  3. RewriteEngine On
  4. RewriteCond %{REQUEST_FILENAME} !-d
  5. RewriteCond %{REQUEST_FILENAME} !-f
  6. RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1]
  7. RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
  8. </IfModule>

隐藏public目录

一个设置即可,网上一堆垃圾错误博客
image.png

设置自定义路由

路由有2种方式,一个是根据类名>方法名> 这种的,就是pathInfo类型。这种不推荐。麻烦。
还有是自定义路由,就是专门有一个文件定义好路由,这个推荐。

建议设置自定义 :
// 是否强制使用路由
‘url_route_must’ => true,
// 路由使用完整匹配
‘route_complete_match’ => true,
图片3.png
设置路由

图片4.png

  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. use think\facade\Route;
  12. /**
  13. * 匿名路由
  14. */
  15. Route::get('think', function () {
  16. return 'hello,ThinkPHP5!';
  17. });
  18. /**
  19. * 带参数的路由 http://127.0.0.1/hello/tom
  20. *
  21. * hello,tom
  22. */
  23. Route::get('hello/:name', 'index/hello');
  24. /**
  25. * 普通路由。 千万别加 设置成 /index/index/hello
  26. */
  27. Route::get('dd', 'index/index/hello');
  28. return [
  29. ];

路由的分组

image.png

  1. Route::group('分组名(字符串)或者分组路由参数(数组)','分组路由规则(数组或者闭包)');
  2. Route::group('blog', function () {
  3. Route::get(':id', 'read');
  4. Route::post(':id', 'update');
  5. Route::delete(':id', 'delete');
  6. })->pattern(['id' => '\d+']);
  7. # 分组的嵌套
  8. Route::group(['method'=>'get'], function () {
  9. Route::group('blog',function(){
  10. Route::get(':id', 'read');
  11. Route::post(':id', 'update');
  12. Route::delete(':id', 'delete');
  13. });
  14. })->pattern(['id' => '\d+']);

图片15.png

通常的写法

  1. /**
  2. * 实际上请求 :http://www.tk.com/aa/indexxx 就是请求的是 http://www.tk.com/index/index/index
  3. *
  4. * 'name'=>'aa' 是自定义前缀
  5. * 'prefix'=>'index/index/' 把全路径给提出来,方便
  6. * indexxx 是路由名
  7. * index 是实际要去找的方法名
  8. */
  9. Route::group(['name'=>'aa','prefix'=>'index/index/'],function (){
  10. Route::get('indexxx','index');
  11. });

路由参数

1、路径上的参数

  1. # 必填参数
  2. Route::请求方式('路由表达式/:参数',匿名函数);
  3. # 可选参数
  4. Route::请求方式('路由表达式/[:参数]',匿名函数);

图片13.png

图片14.png

2、get参数/Post/通用参数

变量类型方法(‘变量名/变量修饰符’,’默认值’,’过滤方法’)

  1. use think\facade\Request;
  2. Request::get();
  3. Request::post()
  4. Request::param();

图片16.png
图片17.png

  1. public function req(Request $request) {
  2. // 门面方式获取数据 use think\facade\Request
  3. /*
  4. // GET的获取
  5. #echo Request::get('id');
  6. // 如果没有则使用默认值
  7. #echo Request::get('age',20);
  8. #echo Request::get('age',20,'intval');
  9. // 获取get全部数据
  10. #dump(Request::get());
  11. // 判断一个key是否存在
  12. #dump(Request::has('sex'));
  13. // 获取指定的数据 白名单
  14. #dump(Request::only(['id','age']));
  15. // 排除不要的数据 黑名单
  16. #dump(Request::except(['id']));
  17. // POST获取
  18. #dump(Request::post('name'));
  19. // PUT获取
  20. #dump(Request::put('name'));
  21. // DELETE获取
  22. #dump(Request::delete('name'));
  23. // 获取任意类型
  24. #dump(Request::param('name'));
  25. // 判断请求的类型
  26. dump(Request::isPost());
  27. dump(Request::isGet());
  28. dump(Request::isPut());
  29. dump(Request::isDelete());
  30. // 是否是ajax请求
  31. dump(Request::isAjax());
  32. // $_SERVER一样的
  33. #dump(Request::server());
  34. // 获取环境变量 说白了就是框架定义好的常量
  35. //dump(Request::env());
  36. // 获取路由
  37. dump(Request::route());
  38. */
  39. // 依赖注入方式 [推荐]
  40. #$request = Req::instance(); # tp5.0有人这样来申明,但是我们推荐依赖注入
  41. /*dump($request->get('name'));
  42. dump($request->has('sex'));
  43. dump($request->only(['id']));
  44. dump($request->except(['id']));*/
  45. }

3、input方法(推荐!!!)

好处,不用引入其他类

  1. public function req2() {
  2. // 辅助函数 [推荐]
  3. // 获取GET的全部参数
  4. #dump(input('get.'));
  5. // 获取指定的数据
  6. #dump(input('get.id'));
  7. #dump(input('get.sex','女士'));
  8. // post数据
  9. //dump(input('post.'));
  10. // 获取任意类型的请求
  11. //dump(input('param.'));
  12. //dump(input(''));
  13. // 获取任意类型的 key 为name值 如果get和post优先post
  14. //dump(input('name'));
  15. // 判断一个key是值存在
  16. #dump(input('?name'));
  17. // 使用变量修饰符 a 数组 s 字符串 d 数字
  18. #dump(input('id/d'));
  19. }

控制器

使用命令行创建分组

  1. php think build --module 分组名称

图片5.png

创建控制器

创建控制器的方式有两种:

Ø 手动创建

  1. application/模块目录/controller/目录下
  2. 命名规则:控制器名称(首字母大写) + (控制器后缀,默认没有) + .php

Ø 命令行方式创建【推荐】

  1. php think make:controller --plain 模块名/控制器名
  2. # 参数说明
  3. --plain 标准控制器 (默认创建的控制器是一个资源控制器,所以一般加上此选项)

如果创建时,没有在模块名称,则默认创建到公共模块中 【common】
图片6.png

开启调试模式

默认情况下,错误描述比较模糊,不方便进行错误调试。这种模式通常叫做“部署模式”。
开发阶段可以将框架设置为调试模式,便于进行错误调试:
修改项目目录 config/app.php文件
‘show_error_msg’=false 改为 true;
再将
‘app_debug’ => false 改为 true;
图片7.png
实际开发中,使用第2种方案
图片8.png
APP_DEBUG=true

前置操作

可以为某个或者某些操作指定前置执行的操作方法,设置 beforeActionList属性可以指定某个方法为其他方法的前置操作,数组键名为需要调用的前置方法名,无值的话为当前控制器下所有方法的前置方法。
图片9.png

  1. <?php
  2. namespace app\index\controller;
  3. use think\Controller;
  4. class Index extends Controller
  5. {
  6. protected $beforeActionList = [
  7. "aa" => ["index","hello"]
  8. ];
  9. public function index()
  10. {
  11. return '<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:) </h1><p> ThinkPHP V5.1<br/><span style="font-size:30px">12载初心不改(2006-2018) - 你值得信赖的PHP框架</span></p></div><script type="text/javascript" src="https://tajs.qq.com/stats?sId=64890268" charset="UTF-8"></script><script type="text/javascript" src="https://e.topthink.com/Public/static/client.js"></script><think id="eab4b9f840753f8e7"></think>';
  12. }
  13. public function hello($name = 'ThinkPHP5')
  14. {
  15. return 'hello,' . $name;
  16. }
  17. protected function aa(){
  18. echo "我是前置方法aa";
  19. }
  20. protected function bb(){
  21. echo "我是前置方法bb";
  22. }
  23. }

页面跳转

默认跳转成功的页面

如果你觉得默认太丑,就可以修改这两个文件
image.png

在应用开发中,经常会遇到一些带有提示信息的跳转页面,例如操作成功或者操作错误页面,并且自动跳转到另外一个目标页面。系统的\think\Controller类内置了两个跳转方法success和error,用于页面跳转提示。

图片11.png图片12.png

1.跳转全路径

前提是需要在配置文件中把这个匹配模式打开。不然访问都访问不到

  1. public function index2(){
  2. return $this->success("登录成功","index/index/su");
  3. //简单写法
  4. //同一个模块,同一个控制旗下 可以直接写 方法名
  5. return $this->success("登录成功",url("su"));
  6. //同一个模块,不同的控制器
  7. return $this->success("登录成功",url("demo2/index"));
  8. // 不用的模块 不同的控制器
  9. return $this->success("登录成功",url("index/index/index"));
  10. }
  11. public function su(){
  12. return "我是成功页面";
  13. }

2.自定义路由(推荐!!!)

必须给路由起一个别名!!!!!!
访问:http://www.tk.com/index2 跳转到 http://www.tk.com/aaa.html
设置自定义路由,然后起个别名。

  1. Route::get('index2', 'index/index/index2');
  2. Route::get('aaa', function () {
  3. return 'zzzzzzzzzzzzzz';
  4. })->name('zdy');

然后跳转。

  1. return $this->success("登录成功",url("zdy"));

3.错误页面

  1. return $this->error("我错了");

4.ajax请求

很牛逼,自动识别是返回json还是页面。

页面
image.png

接口

  1. public function ajax(){
  2. return $this->success("登录成功",url("index/index/ajax"),['staus' => 1]);
  3. }

image.png

5.第二种ajax返回(推荐)

由于默认是输出Html输出,所以直接以html页面方式输出响应内容,但也可以设置默认输出为json格式
‘default_return_type’ => ‘json’,
返回json数据,

  1. return json($data,http状态码);
  2. 数据,状态码,返回的自定义请求头数据
  3. return json($data,201,['username'=>'admin','password'=>'admin888']);

重定向

可以使用redirect助手函数进行重定向

  1. redirect('地址或方法名',数组参数);
  2. 推荐使用这个!!!
  3. return redirect(url('index/index/req2', ['id' => 1]));