75142913在线留言
【Laravel笔记】路由知识点合集_PHP技术_网络人

【Laravel笔记】路由知识点合集

Kwok 发表于:2022-03-30 11:30:47 点击:36 评论: 0

除开配置与安装,学习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
标签:laravel笔记Kwok最后编辑于:2022-03-30 16:30:40
0
感谢打赏!

《【Laravel笔记】路由知识点合集》的网友评论(0)

本站推荐阅读

热门点击文章