【PHP框架 | Laravel8 系列3】 - 路由

7 篇文章 1 订阅
本文详细介绍了Laravel8框架中的路由功能,包括基本路由、重定向、视图路由、控制器路由、路由参数、路由命名、路由组、模型绑定、限流、表单方法伪造和访问当前路由等内容。通过实例展示了如何定义和使用这些路由特性,是学习和进阶Laravel路由操作的重要参考。
摘要由CSDN通过智能技术生成

前言:之前在学习并使用 Laravel 框架过程中,全是碎片化掌握,现在重新学习并记录一次学习的过程。

本文内容对应 Laravel8.* 版本。


直达入口:


一、介绍

本文内容根据 Laravel 官网路由模块学习。


Laravel 框架的所有默认路由文件都保存在 routes 目录中。

  • routes 目录
    • api.php api 路由
    • channels.php 验证配置文件
    • console.php 广播事件配置文件
    • web.php 定义 web 页面路由

1.1 基本路由

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::push($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

Route::match(['get', 'post'], '/', function(){
   # 处理多种请求类型的路由 
});
Route::any('/', function(){
    # 处理所有请求类型的路由
});

1.2 重定向路由

Route::redirect('/here', '/there'); 			# 重定向路由
Route::redirect('/here', '/there', 301); 		# 重定向路由,默认返回状态码为 302
Route::permanentRedirect('/here', '/there'); 	# 重定向路由,默认使用 301 状态码返回

1.3 视图路由

# 第一个参数为 URI,第二个参数对应 resources/views 目录中的模板文件名
Route::view('/welcome', 'welcome');

1.4 控制器路由

use App\Http\Controllers\WelcomeController;

# 第一个参数为 URI,第二个参数对应控制器,会调用控制器 中的 show 方法
Route::get('/welcome', [WelcomeController::class, 'show']);

二、路由参数

2.1 必填参数

# 使用 {} 括起来的参数为必填参数, 参数名不能包含 - / 
Route::get('goods_detail/{id}', $callback);

2.2 可选参数

# 使用 {参数名?} 格式的为可选参数,参数名不能包含 - /
Route::get('goods_detail/{id}/top/{is_top?}', $callback);

2.3 正则表达式约束

在路由定义上链式调用 where 方法中来约束路由参数的格式。

# 单个约束
Route::get('goods_detail/{id}', $callback)->where('id', '[0-9]+');

# 数组格式约束多个
Route::get('user_detail/{id}/{name}', $callback)->where(['id'=>'[0-9]+', 'name'=>'[a-z]+']);

# 字符过滤,Laravel 允许除 / 之外的所有字符,可使用正则表达式显式的允许成为占位符的一部分
Route::get('search/{string}', $callback)->where('string', '.*');


# 常用的辅助正则表达式模式
Route::get('user_detail/{id}/{name}', $callback)->whereNumber('id')->whereAlpha('name');

# whereAlpha()、whereAlphaNumeric()、whereNumber()、whereUuid()、assignExpressionToParameters($parameters, $expression)

2.4 全局约束

如果你希望某个参数在每个路由当中都遵循同一个正则表达式约束,则使用 Route::pattern() 方法在 RouteServiceProvider文件 的 boot 方法中定义约束。

# app/Providers/RouteServiceProvider.php 文件
public function boot()
{
    Route::pattern('id', '[0-9]+');
}

三、路由命名

在路由定义上链式调用 name 方法中为路由生成名称,路由名称是唯一的。

3.1 命名

# 闭包函数命名
Route::get('goods_detail/{id}', $callback)->name('goods_detail');

# 指定控制器行为命名
Route::get('goods_detail/', [GoodsController::class, 'show'])->name('goods_detail');

3.2 生成指定路由 URL

# 生成链接
$url = route('goods_detail');

# 生成带参数的链接
$url = route('goods_detail', ['id'=>1]);

# 生成重定向
return redirect()->route('goods_detail');

3.3 检查是否命中路由

如果你想判断当前请求是否指向某个命名过的路由,可链式调用 named 方法来判断。

if ($request->route()->named('goods_detail')){}

四、路由组

路由组允许在大量路由之间共享路由属性,例如中间件、子域名、前缀等。

4.1 中间件

Route::middleware(['first', 'second'])->group(function(){
   Route::get('/', function(){
       # 使用 first 和 second 中间件
   });
    Route::get('goods_detail/{id}', function(){
       # 使用 first 和 second 中间件
    });
});

4.2 子域名路由

# 应在注册根域名路由前注册子域名路由。
Route::domain('{account}.myapp.com')->group(function () {
    Route::get('user/{id}', function ($account, $id) {
        //
    });
});

4.3 路由前缀

prefix() 方法将会为路由组中的每个路由的 URI 添加前缀。

Route::prefix('admin')->group(function(){
   Route::get('users', function(){
       # 访问的URL是 /admin/users
   }); 
});

4.4 路由名称前缀

链式调用name 方法可为路由组中的每个路由添加指定的名称前缀。注意:确保前缀中包含 . 字符。

Route::name('admin.')->group(function(){
    Route::get('users', function(){
        # 最终定义的路由名称是 admin.users
    })->name('users');
});

五、路由与模型绑定

5.1 隐式绑定

在这个例子当中, $user 类型提示为 App\Models\User Eloquent 模型,变量名 $user 与 URI 中的 {user} 相匹配,因此 Laravel 会自动注入与请求 URI 中传入的 ID 匹配的用户模型实例。


如果在数据库中未找到对应的模型实例,则自动生成 404 异常。

# 闭包路由写法
Route::get('api/users/{user}', function(App\Models\User $user){
   return $user->email; 
});

# 控制器写法
Route::get('users/{user}', [UserController::class, 'show']);

# 控制器代码
use App\Http\Controllers\UserController;
use App\Models\User;

public function show(User $user)
{
    return view('user.profile', ['user' => $user]);
}

5.2 自定义匹配键名

默认使用 id 键名来解析 Eloquent 模型,可自定义键名。

use App\Models\Post;
use App\Models\User;

# 限定 $post 通过 slug 字段来检索
Route::get('api/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
    return $post;
});

如果希望模型绑定在检索给定的模型类时,默认使用 id 以外的数据库字段,可重写 Eloquent 模型上的 getRouteKeyName 方法。

/**
 * 获取该模型的路由的自定义键名
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'slug';
}

5.3 显示绑定

要注册显示绑定,使用路由器的 model 方法,绑定参数指定的类。在 app/Providers/RouteServiceProvider.php 文件类的 boot 方法定义显示的绑定。

/**
 * 定义你的路由模型绑定, pattern 过滤器等
 *
 * @return void
 */
public function boot()
{
    Route::model('user', \App\Models\User::class);

    // ...
}

绑定好后,就可以使用了。

# 上边已将 user 参数绑定给了 \App\Models\User 模型,所以 $user 会被注入该路由
Route::get('profile/{user}', function (App\Models\User $user) {
    //
});

5.4 自定义解析逻辑

第一种: 在 app/Providers/RouteServiceProvider.php 文件类的 boot 方法中使用 Route::bind 方法自定义。


/**
 * 定义你的路由模型绑定, pattern 过滤器等
 *
 * @return void
 */
public function boot()
{
    Route::bind('user', function ($value) {
        return App\Models\User::where('name', $value)->firstOrFail();
    });

    // ...
}

第二种:重写 Eloquent 模型上的 resolveRouteBinding 方法。


/**
 * 检查绑定值的模型
 *
 * @param  mixed  $value
 * @param  string|null  $field
 * @return \Illuminate\Database\Eloquent\Model|null
 */
public function resolveRouteBinding($value, $field = null)
{
    return $this->where('name', $value)->firstOrFail();
}

六、回退路由

回退路由是指 没有命中其他路由的情况下才执行的路由。


注意:回退路由应始终是您应用程序注册的最后一个路由。

Route::fallback(function(){
   # 
});

七、限流

限注顾名思义就是限制流量的请求次数,在 app/Providers/RouteServiceProvider.php 文件中定义限流器。


使用 RateLimiter 门面的 for 方法定义。for 方法接受「速率限制器名称」和「闭包返回限制配置」。


具体更多限制时段方法 查看 Illuminate\Cache\RateLimiting\Limit;

7.1 定义限流

# app/Providers/RouteServiceProvider.php 文件

# 1. 默认响应 429 状态码
RateLimiter::for('global', function (Request $request) {
    return Limit::perMinute(1000);
});

# 2. 自定义响应内容,使用 response 方法
RateLimiter::for('global', function (Request $request) {
    return Limit::perMinute(1000)->response(function () {
        return response('Custom response...', 429);
    });
});

# 3. 可用 $request 实例调取参数,VIP 无限制,不是 VIP 则按身份验证请求频率
RateLimiter::for('uploads', function (Request $request) {
    return $request->user()->vipCustomer()
        ? Limit::none()
        : Limit::perMinute(100);
});

# 4. 范围频率限制
RateLimiter::for('uploads', function (Request $request) {
    return $request->user()->vipCustomer()
        ? Limit::none()
        : Limit::perMinute(100)->by($request->ip());
});

# 5. 多个频率限制
RateLimiter::for('login', function (Request $request) {
    return [
        Limit::perMinute(500),
        Limit::perMinute(3)->by($request->input('email')),
    ];
});

7.2 路由器分配限流

使用 throttle 关键字将配置好的频率限制器名称放到中间件 middleware 数组中。

Route::middleware(['throttle:uploads'])->group(function () {
    Route::post('/audio', function () {
        //
    });

    Route::post('/video', function () {
        //
    });
});

八、表单方法伪造

Html 表单不支持 putpatchdelete 请求,但可以在 form 表单中添加 _method 隐藏域来实现以上请求。

<form action="/foo/bar" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>

// 或

<form action="/foo/bar" method="POST">
    @method('PUT')
    @csrf
</form>

九、访问当前路由

$route = Route::current();

$name = Route::currentRouteName();

$action = Route::currentRouteAction();
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后端木木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值