1.1 路由定义

路由的基本两个作用:1. 美化url 2.隐藏路径使之更加安全,几乎所有的框架无论前后台框架,vue.js、node.js、tp、laravel 中都会单独给路由划分一个模块,它的核心作用其实就只有一件事,分发请求。根据url的路径去判断和处理,返回不同的处理结果给用户,路由文件都存放在 routes 目录下:这些文件都由框架自动加载。如下图
image.png


1.2 基本路由

构建基本路由只需要一个 URI 与一个 闭包. 下面展示了 laravel 下入口文件 public/index.php 下使用的路由。 这才是实际上的首页面 resources\views\welcome.blade.php,它是一个视图路由。

  1. <?php
  2. use Illuminate\Routing\Router;
  3. use Illuminate\Support\Facades\Route;
  4. Route::get('/', function () {
  5. return view('welcome');
  6. });

Laravel中提供了这些常见的方法去使用路由

  1. <?php
  2. Route::get($uri, $callback);
  3. Route::post($uri, $callback);
  4. Route::put($uri, $callback);
  5. Route::patch($uri, $callback);
  6. Route::delete($uri, $callback);
  7. Route::options($uri, $callback);

1.3 自定义路由

1.3.1 创建路由文件

Routes/web.php 文件下先模仿它创建一个文件 my.php ,在其中构建一个最基本的路由。注意这里的路由是区分大小写的

  1. <?php
  2. use Illuminate\Routing\Router;
  3. use Illuminate\Support\Facades\Route;
  4. /**
  5. * 1. 路由基本
  6. */
  7. // 构建一个基本路由
  8. Route::get('say', function () {
  9. return 'Say Hi';
  10. });

1.3.2 注册路由

去这里注册自己的路由 app/Providers/RouteServiceProvider.php,简单来说就是去路由服务提供者类中去注册路由,去掉多余的部分,我们模仿其他注册的路由,添加一个方法 protected function mapMyRoutes(),并且去 map() 方法中完成映射

  1. <?php
  2. namespace App\Providers;
  3. use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
  4. use Illuminate\Support\Facades\Route;
  5. /**
  6. * 路由服务提供类,继承于服务提供类
  7. */
  8. class RouteServiceProvider extends ServiceProvider
  9. {
  10. ... ...
  11. public function map()
  12. {
  13. $this->mapApiRoutes();
  14. $this->mapWebRoutes();
  15. $this->mapMyRoutes();
  16. }
  17. protected function mapMyRoutes()
  18. {
  19. Route::middleware('web')
  20. ->namespace($this->namespace)
  21. ->group(base_path('routes/my.php'));
  22. }
  23. ... ...
  24. }

1.3.2 使用

直接 postman 测试,OK。
image.png


1.4 CSRF 保护

继续在my.php 中添加路由规则,我们发现并不可行。这是因为CSRF的保护机制

my.php 中添加的内容

  1. <?php
  2. Route::post('lxm', function () {
  3. return 'for to lxm';
  4. });

1.4.1 放行白名单

第一种方式:添加放行白名单,位置 app/Http/Middleware/VerifyCsrfToken.php

  1. <?php
  2. namespace App\Http\Middleware;
  3. use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
  4. class VerifyCsrfToken extends Middleware
  5. {
  6. protected $except = [
  7. 'lxm', // 加在了这里
  8. ];
  9. }

然后去访问,OK
image.png

1.4.2 取消这个中间件CSRF验证

第二种使用方式:取消这个中间件 app/Http/Kernel.php 下注释这个验证 CSRF (但是,我们一般不这样做,当然也不推荐这么做)

  1. <?php
  2. namespace App\Http;
  3. use Illuminate\Foundation\Http\Kernel as HttpKernel;
  4. class Kernel extends HttpKernel
  5. {
  6. protected $middlewareGroups = [
  7. 'web' => [
  8. \App\Http\Middleware\EncryptCookies::class,
  9. \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
  10. \Illuminate\Session\Middleware\StartSession::class,
  11. // \Illuminate\Session\Middleware\AuthenticateSession::class,
  12. \Illuminate\View\Middleware\ShareErrorsFromSession::class,
  13. // \App\Http\Middleware\VerifyCsrfToken::class, // 就是这里
  14. \Illuminate\Routing\Middleware\SubstituteBindings::class,
  15. ],
  16. 'api' => [
  17. 'throttle:60,1',
  18. \Illuminate\Routing\Middleware\SubstituteBindings::class,
  19. ],
  20. ];
  21. }

同样OK
image.png


1.5 路由匹配的请求

http 的请求有很多种,我们知道远远不止 get、post,这里有两种方式对这些请求进行处理。

1.5.1 match

匹配多种请求方式,用一个数组来挂载我们需要的请求。

  1. /**
  2. * match 匹配多种访问方式
  3. */
  4. Route::match(['get', 'post', 'put'], 'link', function () {
  5. return 'for to link';
  6. });

1.5.2 any

几乎大多数的请求都可以。

  1. /**
  2. * any 几乎可以匹配所有的访问方式
  3. */
  4. Route::any('park', function () {
  5. return 'for to park';
  6. });

1.6 路由参数

  • 使用get请求传递参数,同样的像其他框架一样为了保持url的美丽
    • a. 使用/隔开参数
    • b. 必须有{},其中包含我们的参数
    • c. 这个参数可以是单个也可以是多个,后面的那个回调函数进行形参的传递,顺序对应了就好了

1.6.1 单个参数

  1. <?php
  2. /**
  3. * 单个参数
  4. */
  5. Route::get('user1/{id}', function ($id) {
  6. return '传递的用户ID:' . $id;
  7. });

image.png

1.6.2 多个参数

  1. <?php
  2. Route::get('user2/{id}/{name}/{age}', function ($p1, $p2, $p3) {
  3. return 'id:' . $p1 . ',' . 'name:' . $p2 . ',' . 'age:' . $p3;
  4. });

image.png

1.6.3 可选参数

  • 必选参数和可选参数
    • 可选:同样的也可以使用可选参数{id?},标记一个?来标记这是一个可选按参数 只是,我每标记一个可选参数,就必定需要在后面得到回调闭包中给定一个默认值 ,一般我们将可选的放在最后,防止匹配出错
    • 必选:像是上面那种使用方式,就是必选参数,规定必须将参数传递过来
  1. <?php
  2. // 我测试一下,不传递age
  3. Route::get('user3/{id}/{name}/{age?}', function ($id, $name, $age = 24) {
  4. return 'id:' . $id . ',' . 'name:' . $name . ',' . 'age:' . $age;
  5. });

image.png


1.7 使用正则约束

1.7.1 正则约束

  • a. 可以单个约束
  • b. 可以多个约束
  • c. where链式结构的操作觉得麻烦的话使用数组的方法,因为PHP中数组这个强大的数据结构,是关联数组十分好用 …..
  1. <?php
  2. Route::get('user4/{name}', function ($name) {
  3. //
  4. })->where('name', '[A-Za-z]+');
  5. Route::get('user4/{id}', function ($id) {
  6. //
  7. })->where('id', '[0-9]+');
  8. Route::get('user4/{id}/{name}', function ($id, $name) {
  9. //
  10. })->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

1.7.2 全局约束

如果你希望某个具体的路由参数都遵循同一个正则表达式的约束,就使用 pattern 方法在 app\Providers\RouteServiceProvider.php 的 boot 方法中定义这些模式:

  1. <?php
  2. /**
  3. * Define your route model bindings, pattern filters, etc.
  4. * 全局限定, 可以在这里限制, 这个限制是所有路由生效之前的限制
  5. * @return void
  6. */
  7. public function boot()
  8. {
  9. //
  10. // Route::pattern('id', '[0-9]+'); // 加在了这里
  11. parent::boot();
  12. }

1.8 路由组中的使用

1.8.1 路由命名

  • 路由命名,为路由重定向服务。如下面的操作, 我觉得有时候访问 a/b/c/d 这个也太长了,但是我也需要保留这个路由,这个时候我们就可以通过给这个路由一个name,其实相当于一个别名,然后我们通过其他的路由,重定向到这个路由,这个name必不可少
  1. <?php
  2. Route::get('a/b/c/d', function () {
  3. return 'in aaa';
  4. })->name('d');
  5. Route::get('e', function () {
  6. return redirect()->route('d');
  7. });

下面我通过访问e,来访问a/b/c/d
image.png

1.8.3 路由前缀

给一组路由统一规范,如下面的代码。

  1. <?php
  2. /**
  3. * 路由前缀
  4. */
  5. Route::prefix('admin')->group(function () {
  6. Route::get('addUser', function () {
  7. return 'addUser';
  8. });
  9. Route::get('editUser', function () {
  10. return 'editUser';
  11. });
  12. Route::get('delUser', function () {
  13. return 'delUser';
  14. });
  15. Route::get('updateUser', function () {
  16. return 'updateUser';
  17. });
  18. });

访问admin/addUser
image.png

1.8.3 路由名称前缀

  1. <?php
  2. /**
  3. * 路由名称前缀
  4. */
  5. Route::name('admin.')->group(function () {
  6. Route::get('addUser', function () {
  7. return '添加用户';
  8. })->name('add');
  9. Route::get('delUser', function () {
  10. return '删除用户';
  11. })->name('del');
  12. Route::get('editUser', function () {
  13. return '修改用户';
  14. })->name('edit');
  15. Route::get('selUser', function () {
  16. return '查询用户';
  17. })->name('sel');
  18. });
  19. /**
  20. * 下面重定向一下
  21. */
  22. Route::get('1', function () {
  23. return redirect()->route('admin.add');
  24. });
  25. Route::get('2', function () {
  26. return redirect()->route('admin.del');
  27. });
  28. Route::get('3', function () {
  29. return redirect()->route('admin.edit');
  30. });
  31. Route::get('4', function () {
  32. return redirect()->route('admin.sel');
  33. });

下面我通过访问 1、2、3、4,来进而处理页面的CURD请求
1
image.png
2
image.png
3
image.png
4
image.png

1.8.4 domain 访问控制

如下,我进行域名限制,要求只能够通过 blog.com 下的域名才是有效的请求路径

  1. <?php
  2. /**
  3. * 子域名路由
  4. */
  5. Route::domain('blog.com')->group(function () {
  6. Route::get('user/{id}', function ($id) {
  7. return "访问ID是 $id";
  8. });
  9. });

正常访问
image.png


1.8.5 路由组链式调用及数组

  1. <?php
  2. /**
  3. * 链式调用和数组
  4. */
  5. Route::prefix('larave')->name('admin')->group(function(){
  6. Route::get('lyym',function(){
  7. return '检测路由域名';
  8. });
  9. });
  10. Route::group(['prefix'=>'admin','domain'=>'blog.com'],function(){
  11. Route::get('lyhh',function(){
  12. return '数组方式';
  13. });
  14. });

1.9 路由中间件

1.9.1 创建中间件

  • 项目根目录下运行:php artisan make:middleware 中间件名称

如下图创建了一个叫做Test的中间件
image.png

1.9.2 编写中间件

打开干刚刚创建的Test中间件,加入line18这行代码

  1. <?php
  2. namespace App\Http\Middleware;
  3. use Closure;
  4. class Test
  5. {
  6. /**
  7. * Handle an incoming request.
  8. *
  9. * @param \Illuminate\Http\Request $request
  10. * @param \Closure $next
  11. * @return mixed
  12. */
  13. public function handle($request, Closure $next)
  14. {
  15. echo "我是中间件 Test \r";
  16. return $next($request);
  17. }
  18. }

1.9.3 注册中间件

blog\app\Http\Kernel.php$routeMiddleware中注册对应的中间件,注意写上自定义中间件的命名空间,要不会找不到的。

  1. <?php
  2. namespace App\Http;
  3. use App\Http\Middleware\Test; // 注意这里也要写,否则找不到
  4. use Illuminate\Foundation\Http\Kernel as HttpKernel;
  5. class Kernel extends HttpKernel
  6. {
  7. protected $routeMiddleware = [
  8. 'auth' => \App\Http\Middleware\Authenticate::class,
  9. 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
  10. 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
  11. 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
  12. 'can' => \Illuminate\Auth\Middleware\Authorize::class,
  13. 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
  14. 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
  15. 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
  16. 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
  17. 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
  18. // 'test' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
  19. 'test' => Test::class, // 写这里了
  20. ];
  21. }

1.9.4 使用中间件

  1. <?php
  2. # 使用
  3. Route::middleware('test')->group(function(){
  4. Route::get('ly',function(){
  5. return '检测路由中间件';
  6. });
  7. });

OK
image.png


1.10 命名空间


1.11 回退路由