1.1 路由定义
路由的基本两个作用:1. 美化url 2.隐藏路径使之更加安全,几乎所有的框架无论前后台框架,vue.js、node.js、tp、laravel 中都会单独给路由划分一个模块,它的核心作用其实就只有一件事,分发请求。根据url的路径去判断和处理,返回不同的处理结果给用户,路由文件都存放在 routes 目录下:这些文件都由框架自动加载。如下图
1.2 基本路由
构建基本路由只需要一个 URI 与一个 闭包. 下面展示了 laravel 下入口文件 public/index.php 下使用的路由。 这才是实际上的首页面 resources\views\welcome.blade.php,它是一个视图路由。
<?phpuse Illuminate\Routing\Router;use Illuminate\Support\Facades\Route;Route::get('/', function () {return view('welcome');});
Laravel中提供了这些常见的方法去使用路由
<?phpRoute::get($uri, $callback);Route::post($uri, $callback);Route::put($uri, $callback);Route::patch($uri, $callback);Route::delete($uri, $callback);Route::options($uri, $callback);
1.3 自定义路由
1.3.1 创建路由文件
在 Routes/web.php 文件下先模仿它创建一个文件 my.php ,在其中构建一个最基本的路由。注意这里的路由是区分大小写的
<?phpuse Illuminate\Routing\Router;use Illuminate\Support\Facades\Route;/*** 1. 路由基本*/// 构建一个基本路由Route::get('say', function () {return 'Say Hi';});
1.3.2 注册路由
去这里注册自己的路由 app/Providers/RouteServiceProvider.php,简单来说就是去路由服务提供者类中去注册路由,去掉多余的部分,我们模仿其他注册的路由,添加一个方法 protected function mapMyRoutes(),并且去 map() 方法中完成映射
<?phpnamespace App\Providers;use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;use Illuminate\Support\Facades\Route;/*** 路由服务提供类,继承于服务提供类*/class RouteServiceProvider extends ServiceProvider{... ...public function map(){$this->mapApiRoutes();$this->mapWebRoutes();$this->mapMyRoutes();}protected function mapMyRoutes(){Route::middleware('web')->namespace($this->namespace)->group(base_path('routes/my.php'));}... ...}
1.3.2 使用
直接 postman 测试,OK。
1.4 CSRF 保护
继续在my.php 中添加路由规则,我们发现并不可行。这是因为CSRF的保护机制
my.php 中添加的内容
<?phpRoute::post('lxm', function () {return 'for to lxm';});
1.4.1 放行白名单
第一种方式:添加放行白名单,位置 app/Http/Middleware/VerifyCsrfToken.php
<?phpnamespace App\Http\Middleware;use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;class VerifyCsrfToken extends Middleware{protected $except = ['lxm', // 加在了这里];}
1.4.2 取消这个中间件CSRF验证
第二种使用方式:取消这个中间件 app/Http/Kernel.php 下注释这个验证 CSRF (但是,我们一般不这样做,当然也不推荐这么做)
<?phpnamespace App\Http;use Illuminate\Foundation\Http\Kernel as HttpKernel;class Kernel extends HttpKernel{protected $middlewareGroups = ['web' => [\App\Http\Middleware\EncryptCookies::class,\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,\Illuminate\Session\Middleware\StartSession::class,// \Illuminate\Session\Middleware\AuthenticateSession::class,\Illuminate\View\Middleware\ShareErrorsFromSession::class,// \App\Http\Middleware\VerifyCsrfToken::class, // 就是这里\Illuminate\Routing\Middleware\SubstituteBindings::class,],'api' => ['throttle:60,1',\Illuminate\Routing\Middleware\SubstituteBindings::class,],];}
同样OK
1.5 路由匹配的请求
http 的请求有很多种,我们知道远远不止 get、post,这里有两种方式对这些请求进行处理。
1.5.1 match
匹配多种请求方式,用一个数组来挂载我们需要的请求。
/*** match 匹配多种访问方式*/Route::match(['get', 'post', 'put'], 'link', function () {return 'for to link';});
1.5.2 any
几乎大多数的请求都可以。
/*** any 几乎可以匹配所有的访问方式*/Route::any('park', function () {return 'for to park';});
1.6 路由参数
- 使用get请求传递参数,同样的像其他框架一样为了保持url的美丽
- a. 使用/隔开参数
- b. 必须有{},其中包含我们的参数
- c. 这个参数可以是单个也可以是多个,后面的那个回调函数进行形参的传递,顺序对应了就好了
1.6.1 单个参数
<?php/*** 单个参数*/Route::get('user1/{id}', function ($id) {return '传递的用户ID:' . $id;});
1.6.2 多个参数
<?phpRoute::get('user2/{id}/{name}/{age}', function ($p1, $p2, $p3) {return 'id:' . $p1 . ',' . 'name:' . $p2 . ',' . 'age:' . $p3;});

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

1.7 使用正则约束
1.7.1 正则约束
- a. 可以单个约束
- b. 可以多个约束
- c. where链式结构的操作觉得麻烦的话使用数组的方法,因为PHP中数组这个强大的数据结构,是关联数组十分好用 …..
<?phpRoute::get('user4/{name}', function ($name) {//})->where('name', '[A-Za-z]+');Route::get('user4/{id}', function ($id) {//})->where('id', '[0-9]+');Route::get('user4/{id}/{name}', function ($id, $name) {//})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
1.7.2 全局约束
如果你希望某个具体的路由参数都遵循同一个正则表达式的约束,就使用 pattern 方法在
app\Providers\RouteServiceProvider.php的 boot 方法中定义这些模式:
<?php/*** Define your route model bindings, pattern filters, etc.* 全局限定, 可以在这里限制, 这个限制是所有路由生效之前的限制* @return void*/public function boot(){//// Route::pattern('id', '[0-9]+'); // 加在了这里parent::boot();}
1.8 路由组中的使用
1.8.1 路由命名
- 路由命名,为路由重定向服务。如下面的操作, 我觉得有时候访问 a/b/c/d 这个也太长了,但是我也需要保留这个路由,这个时候我们就可以通过给这个路由一个name,其实相当于一个别名,然后我们通过其他的路由,重定向到这个路由,这个name必不可少
<?phpRoute::get('a/b/c/d', function () {return 'in aaa';})->name('d');Route::get('e', function () {return redirect()->route('d');});
1.8.3 路由前缀
给一组路由统一规范,如下面的代码。
<?php/*** 路由前缀*/Route::prefix('admin')->group(function () {Route::get('addUser', function () {return 'addUser';});Route::get('editUser', function () {return 'editUser';});Route::get('delUser', function () {return 'delUser';});Route::get('updateUser', function () {return 'updateUser';});});
1.8.3 路由名称前缀
<?php/*** 路由名称前缀*/Route::name('admin.')->group(function () {Route::get('addUser', function () {return '添加用户';})->name('add');Route::get('delUser', function () {return '删除用户';})->name('del');Route::get('editUser', function () {return '修改用户';})->name('edit');Route::get('selUser', function () {return '查询用户';})->name('sel');});/*** 下面重定向一下*/Route::get('1', function () {return redirect()->route('admin.add');});Route::get('2', function () {return redirect()->route('admin.del');});Route::get('3', function () {return redirect()->route('admin.edit');});Route::get('4', function () {return redirect()->route('admin.sel');});
下面我通过访问 1、2、3、4,来进而处理页面的CURD请求
1
2
3
4
1.8.4 domain 访问控制
如下,我进行域名限制,要求只能够通过 blog.com 下的域名才是有效的请求路径
<?php/*** 子域名路由*/Route::domain('blog.com')->group(function () {Route::get('user/{id}', function ($id) {return "访问ID是 $id";});});
正常访问
1.8.5 路由组链式调用及数组
<?php/*** 链式调用和数组*/Route::prefix('larave')->name('admin')->group(function(){Route::get('lyym',function(){return '检测路由域名';});});Route::group(['prefix'=>'admin','domain'=>'blog.com'],function(){Route::get('lyhh',function(){return '数组方式';});});
1.9 路由中间件
1.9.1 创建中间件
- 项目根目录下运行:
php artisan make:middleware 中间件名称
如下图创建了一个叫做Test的中间件
1.9.2 编写中间件
打开干刚刚创建的Test中间件,加入line18这行代码
<?phpnamespace App\Http\Middleware;use Closure;class Test{/*** Handle an incoming request.** @param \Illuminate\Http\Request $request* @param \Closure $next* @return mixed*/public function handle($request, Closure $next){echo "我是中间件 Test \r";return $next($request);}}
1.9.3 注册中间件
blog\app\Http\Kernel.php 的$routeMiddleware中注册对应的中间件,注意写上自定义中间件的命名空间,要不会找不到的。
<?phpnamespace App\Http;use App\Http\Middleware\Test; // 注意这里也要写,否则找不到use Illuminate\Foundation\Http\Kernel as HttpKernel;class Kernel extends HttpKernel{protected $routeMiddleware = ['auth' => \App\Http\Middleware\Authenticate::class,'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,'can' => \Illuminate\Auth\Middleware\Authorize::class,'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,// 'test' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,'test' => Test::class, // 写这里了];}
1.9.4 使用中间件
<?php# 使用Route::middleware('test')->group(function(){Route::get('ly',function(){return '检测路由中间件';});});
OK
