除开配置与安装,学习laravel的第一步应该就是从路由开始了,laravel接受的是一个闭包,使用简单优雅的方法来定义路由和行为。
所有 Laravel 路由都定义在你的路由文件 /routes 目录中。此目录下的文件会应用程序中的 AppProvidersRouteServiceProvider 自动加载。 下面针对这几个文件简单说明一下:
routes/web.php: 定义 web 界面的路由,提供了SESSION 状态和 CSRF(防止跨域表单提交) 保护等功能。
routes/api.php:分配了 api 中间件组。无SESSION 状态。/api路径由 RouteServiceProvider 嵌套在一个路由组内。 在这个路由组内,将自动应用 /api URI 前缀,所以我们不需要在里面以/api/来定义路由。
还有channels.php(广播频道路由)与console.php(控制台路由)文件在后台使用到的时候再学吧~
当路由量过多(超过数百条时)我们需要将路由缓存起来,使用:php artisan route:cache 命令。
大部分情况下都是从routes/web.php开始的,当然开发api只是路由的文件不同,所定义的方式都是一样的。所以routes/web.php指定了一个默认的路由。Laravel 路由组件允许除" / "之外的所有字符出现在路由参数值中,也不能使用:view, data,status,和 headers这几个保留路由。
1、单个路由(默认内置)
//请求路径‘/’返回视图‘welcome’
Route::get('/', function () {
//return 'Hello world!';//试试取消本行注释
return view('welcome'); //使用模板 resources/views/welcome.blade.php
});
上面使用了 使用 Route::view
方法返回了一个视图路由,view
方法有三个参数,其中前两个是必填参数,上面在get里传递了URL,所以下面演示使用第3个参数->传值。
Route::view('/welcome', 'welcome', ['name' => 'Kwok']);
将变量name传入到welcom模板里,我们在模板里使用: {{ $name }} 接收传入的Kowk值。
假如要定义本文章的路由为下:
Route::get('/php/203.html', function () {
return '【laravel笔记】路由知识点合集!';
});
上面代码只能匹配当前的URL,因为我把文章ID写死为203,所以如果要访问上一篇202.html就要重新写一行路由?当前不需要,所以下接着向下看。
小知识(Tips):
其实现原理为"伪静态"方式,Nginx通过核心模块里面的try_files指令来实现伪静态,而且只需要一行配置代码:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
try_files这个指令可以按照参数顺序检查文件是否存在,以及返回第一个被找到的文件名,以"/"结尾的表示一个目录。如果文件没有找到,将被内部重定向到最后一个参数上。最后的参数是一个后备的URI,它必须存在,否则会报内部错误。
2、参数匹配
a.必选参数匹配:通过向闭包传递参数$id以匹配文章ID。
Route::get('/php/{id}.html', function ($id) {
return '文章ID: ' . $id;
});
上面正常情况下都是可以匹配到内容,但是如果我们在浏览器里输入URL:/php/2023html222.html 时同样也可以匹配,这样就有问题。我们需要请$id的值限制为数字如果使用下面的代码:
b.限制参数类型:在路由结尾加where 方法来限制路由参数的格式。
Route::get('/php/{id}.html', function ($id) {
return '文章ID: ' . $id;
})->where('id', '[0-9]+');//限制ID为数字
where 方法接受参数的名称和定义如何约束参数的正则表达式。
为了方便(不会写正则),一些常用的正则表达式已内置到方法里了:
Route::get('/user/{id}/{name}', function ($id, $name) {
//限制id为数字[0-9]+,name为字母[a-z]+
})->whereNumber('id')->whereAlpha('name');
Route::get('/user/{id}', function ($id) {
//匹配UUID(da820c0f-c3bb-4fbe-929e-d498f1024a41)
})->whereUuid('id');
c、匹配多个参数:
Route::get('/{path}/{id}.html', function ($pathDIR, $id) {
return '目录:' . $pathDIR . ',文章ID:' . $id;
})->where(['id' => '[0-9]+', 'path' => '[a-z]+']);//限制目录为字母,文章ID为数字
路由的参数通常都会被放在 {} ,并且参数名只能为字母。下划线 (_) 也可以用于路由参数名中。路由参数会按路由定义的顺序依次注入到路由回调或者控制器中 - ,而不受回调或者控制器的参数名称的影响({path} -> $pathDIR)。
d.可选参数:有时,你可能需要指定一个路由参数,但你希望这个参数是可选的。你可以在参数后面加上 ? 标记来实现,但前提是要确保路由的相应变量有默认值:
//和swift语言一下,可选值通过?修饰
Route::get('/who/{name?}', function ($name = 'Kwok 网络人') {
return $name;
});
在浏览器里输入:/who、/who/张三,可以看到没有默认值的时候输入默认值。
e.允许/出现在路由里:匹配/search/分类名/作者名/文章名 这样的路由。
Route::get('/cat/{search}', function ($search) {
return $search;
})->where('search', '.*');//允许“/”出险在{search}里
3、可用的路由请求方法
Laravel路由器允许下面的HTTP请求方法,这在我们使用ResfulAPI编程的时候特别好用~
Route::get($uri, $callback); //接收GET方法请求
Route::post($uri, $callback); //接收POST方法请求
Route::put($uri, $callback); //接收PUT方法请求
Route::patch($uri, $callback);//接收patch方法请求
Route::delete($uri, $callback);//接收delete方法请求
Route::options($uri, $callback);//接收options方法请求
除了上面的几种HTTP请求方法,如果我个页面需要同时接收多个请求的时候Laravel还有以下几种可灵活使用的路由处理方法:
Route::match(['get', 'post'], '/', function () {
//只接收get与post请求。
});
Route::any('/', function () {
//接收所有请求
});
技巧:当定义多个相同路由时,使用 get, post, put, patch, delete, 和 options 方法的路由应该在使用 any, match, 和 redirect 方法的路由之前定义,这样可以确保请求与正确的路由匹配。
4、重定向(301跳转):
Route::redirect('/one', '/two');//302 临时
Route::redirect('/one', '/two',301);//301 永久
Route::permanentRedirect('/one', '/two');//301 永久
看到这里,基本上就可以将上面的路由知识应用到我们的大部开发项目中了,下面将介绍的是一些更为方便的路由解析高级应用和技巧。
5、限制子域名路由
Route::domain('{account}.55mx.com')->group(function () {
Route::get('user/{id}', function ($account, $id) {
//仅在当前子域名上匹配路由
});
});
6、路由前缀匹配(利用路由分组)
Route::prefix('article')->group(function () {
Route::get('{id}', function ($id) {
return route('article', ['id' => $id]);
// 匹配 /article/12345
});
});
//name 方法可以用给定字符串作为组中的每个路由名的前缀。例如,你可能想要用 admin 作为所有分组路由的前缀。因为给定字符串的前缀与指定的路由名完全一致,所以我们一定要提供末尾 . 字符在前缀中:
Route::name('article.')->group(function () {
Route::get('{id}', function ($id) {
// 路由分配的名称为“article.myid”…
})->name('myid');
});
最后的路由:fallback
通常情况下,不能匹配的路由会返回404页面,我们需要处理这些不匹配的路径就要使用到fallback路由。
Route::fallback(function () {
//这里可以写一些日志记录神马的。。。。
return redirect('/');//回到网站首页
});
本文中出现的都是以闭包的形势来处理请求,更高级的用户是使用控制器,关于控制器使用,我们需要新建一个文章来说明:
1、全局约束:在团队开发中,我们需要将某些有意义的参数强制使用某种数据类型时,可以使用全局约束功能:
这些路由参数始终受给定正则表达式的约束,打开 AppProvidersRouteServiceProvider 类的 boot 方法中使用 pattern 方法定义这些模式:
public function boot()
{
Route::pattern('id', '[0-9]+');//ID为数字
Route::pattern('name', '[a-z]+');//name为字母
Route::pattern('page', '[0-9]+');//Page为数字
}
2、路由命名:为特定路由方便地生成 URL 或重定向。通过将 name 方法链接到路由定义上,可以指定路由的名称:
//将些路径命名为“article”,并使用article控制器操作当前的路由
Route::get('/{path}/{id}.html',[UserProfileController::class, 'article'])->name('article');
这里的命名:article不能再拿来去命名其它路由组了,始终是唯一的,否则命名将被最后的使用者所替换掉。路由命名后我们可以拿来做什么呢?
一旦为路由分配了一个名字,就以在通过 Laravel 的 route 和 redirect 辅助函数生成 URL 或重定向时使用该路由的名称:
Route::get('/getarticle/{path}/{id}', function ($pathDIR, $id) {
return '文章的的URL' . route('article', ['id' => $id, 'path' => 'php']);
});
访问:http://www.55mx.com/getarticle/php/203 输出的结果:文章的的URL:http://www.55mx.com/php/204.html
也可以使用重定向方法转到新地址:
redirect()->route('article', ['id' => $id, 'path' => 'php']);
4、返回当前路由
use IlluminateSupportFacadesRoute;
$route = Route::current(); // IlluminateRoutingRoute
$name = Route::currentRouteName(); // string
$action = Route::currentRouteAction(); // string
5、流量限制
在AppProvidersRouteServiceProvider 类的 configureRateLimiting 方法中配置速度限制。
use IlluminateCacheRateLimitingLimit;
use IlluminateSupportFacadesRateLimiter;
protected function configureRateLimiting()
{
RateLimiter::for('global', function (Request $request) {
return Limit::perMinute(1000);
});
}
当超速了会返回一个429的HTTP状态码,如果要自定这个码请使用:
RateLimiter::for('global', function (Request $request) {
return Limit::perMinute(1000)->response(function () {
return response('Custom response...', 429);//修改返回状态
});
});
登陆用户身份验证后的速度限制:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()//是否为VIP
? Limit::none()//不限制
: Limit::perMinute(100);//限制100
});
通过IP、用户ID限制用户速度:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()
? Limit::perMinute(100)->by($request->user()->id)//当前用户ID限制为100次/分钟
: Limit::perMinute(10)->by($request->ip());//当前IP限制为10次/分钟
});
同时返回多个限制规则:
RateLimiter::for('login', function (Request $request) {
return [
Limit::perMinute(500),
Limit::perMinute(3)->by($request->input('email')),
];
});
在路由上限制请求速度:可以使用 throttle middleware 将速率限制器附加到路由或路由组。路由中间件接受你希望分配给路由的速率限制器的名称:
Route::middleware(['throttle:uploads'])->group(function () {
Route::post('/audio', function () {
//音乐上传
});
Route::post('/video', function () {
//视频上传
});
});
使用Redis限制:我们需要在 HTTP 内核 (AppHttpKernel) 中定义(默认为ThrottleRequests,我们需要改为:ThrottleRequestsWithRedis):
'throttle' => IlluminateRoutingMiddlewareThrottleRequestsWithRedis::class,
6、路由组及中间件
要将 middleware 分配给组内的所有路由,你可以在定义组之前使用 middleware 方法。 中间件按照它们在数组中列出的顺序执行:
//利用路由组批量指定中件间
Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// 使用first和second中间件...
});
Route::get('/user/profile', function () {
// 使用first和second中间件...
});
});
利用路由组使用控制器:
use AppHttpControllersOrderController;
Route::controller(OrderController::class)->group(function () {
Route::get('/orders/{id}', 'show');
Route::post('/orders', 'store');
});
除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/203
上一篇:决定重构CMS!
《【Laravel笔记】路由知识点合集》的网友评论(0)