路由
基本路由
最基本的 Laravel 路由接受一个 URI 和一个闭包,提供了一个简单优雅的方法来定义路由和行为,而不需要复杂的路由配置文件:
use Illuminate\Support\Facades\Route;
Route::get('/greeting', function () {
    return 'Hello World';
});
默认路由文件
所有 Laravel 路由都定义在你的路由文件中,它位于 routes 目录。这些文件会被你的应用程序中的 App\Providers\RouteServiceProvider 自动加载。routes/web.php 文件用于定义 web 界面的路由。这些路由被分配给 web 中间件组,它提供了 会话状态和 CSRF 保护等功能。定义在 routes/api.php 中的路由都是无状态的,并且被分配了 api 中间件组。
对于大多数应用程序,都是以在 routes/web.php 文件定义路由开始的。可以通过在浏览器中输入定义的路由 URL 来访问 routes/web.php 中定义的路由。例如,你可以在浏览器中输入 http://example.com/user 来访问以下路由:
use App\Http\Controllers\UserController;
Route::get('/user', [UserController::class, 'index']);
定义在 routes/api.php 文件中的路由是被 RouteServiceProvider 嵌套在一个路由组内。 在这个路由组内,将自动应用 /api URI 前缀,所以你无需手动将其应用于文件中的每个路由。你可以通过修改 RouteServiceProvider 类来修改前缀和其他路由组选项。
可用的路由方法
路由器允许你注册能响应任何 HTTP 请求的路由
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
有的时候你可能需要注册一个可响应多个 HTTP 请求的路由,这时你可以使用 match 方法,也可以使用 any 方法注册一个实现响应所有 HTTP 请求的路由:
Route::match(['get', 'post'], '/', function () {
    // ...
});
Route::any('/', function () {
    // ...
});
当定义多个相同路由时,使用 get, post, put, patch, delete, 和 options 方法的路由应该在使用 any, match, 和 redirect 方法的路由之前定义,这样可以确保请求与正确的路由匹配。
依赖注入
你可以在路由的回调方法中,以形参的方式声明路由所需要的任何依赖项。这些依赖会被 Laravel 的 容器 自动解析并注入。 例如,你可以在闭包中声明 Illuminate\Http\Request 类, 让当前的 HTTP 请求自动注入依赖到你的路由回调中:
use Illuminate\Http\Request;
Route::get('/users', function (Request $request) {
    // ...
});
CSRF 保护
请记住,任何指向POST、PUT、PATCH 或 DELETE 路由(在 web 路由文件中定义)的 HTML 表单都应该包含 CSRF 令牌字,否则请求会被拒绝。更多 CSRF 保护的相关信息请阅读CSRF 文档:
<form method="POST" action="/profile">
    @csrf
    ...
</form>
重定向路由
如果要定义一个重定向到另一个 URI 的路由,可以使用 Route::redirect 方法。这个方法可以快速的实现重定向,而不再需要去定义完整的路由或者控制器:
Route::redirect('/here', '/there');
默认情况下,Route::redirect 返回 302 状态码。你可以使用可选的第三个参数自定义状态码:
Route::redirect('/here', '/there', 301);
或者,你也可以使用 Route::permanentRedirect 方法返回 301状态码:
Route::permanentRedirect('/here', '/there');
在重定向路由中使用路由参数时,以下参数由 Laravel 保留,不能使用:destination 和 status。
视图路由
如果你的路由只需返回一个视图,你可以使用 Route::view 方法。就像 redirect 方法,该方法提供了一个让你不必定义完整路由或控制器的便捷操作。这个view方法的第一个参数是URI,第二个参数为视图名称。此外,你也可以在可选的第三个参数中传入数组,将数组的数据传递给视图:
Route::view('/welcome', 'welcome');
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
在视图路由中使用参数时,下列参数由 Laravel 保留,不能使用:view、data, status 及 headers。
route:list 命令
使用 route:list Artisan命令可以轻松提供应用程序定义的所有路线的概述:
php artisan route:list
正常情况下,route:list不会显示分配给路由的中间件信息;但是你可以通过在命令中添加 -v 选项 来显示路由中的中间件信息:
php artisan route:list -v
你也可以通过 --path 来显示指定的 URL 开头的路由:
php artisan route:list --path=api
此外,在执行 route:list 命令时,可以通过提供 --except vendor 选项来隐藏由第三方包定义的任何路由:
php artisan route:list --except-vendor
同理,也可以通过在执行 route:list 命令时提供 --only vendor 选项来显示由第三方包定义的路由:
php artisan route:list --only-vendor
路由参数
必需参数
有时你将需要捕获路由内的 URI 段。例如,你可能需要从 URL 中捕获用户的 ID。你可以通过定义路由参数来做到这一点:
Route::get('/user/{id}', function (string $id) {
    return 'User '.$id;
});
也可以根据你的需要在路由中定义多个参数:
Route::get('/posts/{post}/comments/{comment}', function (string $postId, string $commentId) {
    // ...
});
路由的参数通常都会被放在 {} ,并且参数名只能为字母。下划线 (_) 也可以用于路由参数名中。路由参数会按路由定义的顺序依次注入到路由回调或者控制器中,而不受回调或者控制器的参数名称的影响。
必填参数
如果你的路由具有依赖关系,而你希望 Laravel 服务容器自动注入到路由的回调中,则应在依赖关系之后列出路由参数:
use Illuminate\Http\Request;
Route::get('/user/{id}', function (Request $request, string $id) {
    return 'User '.$id;
});
可选参数
有时,你可能需要指定一个路由参数,但你希望这个参数是可选的。你可以在参数后面加上 ? 标记来实现,但前提是要确保路由的相应变量有默认值:
Route::get('/user/{name?}', function (string $name = null) {
    return $name;
});
Route::get('/user/{name?}', function (string $name = 'John') {
    return $name;
});
正则表达式约束
你可以使用路由实例上的 where 方法来限制路由参数的格式。 where 方法接受参数的名称和定义如何约束参数的正则表达式:
Route::get('/user/{name}', function (string $name) {
    // ...
})->where('name', '[A-Za-z]+');
Route::get('/user/{id}', function (string $id) {
    // ...
})->where('id', '[0-9]+');
Route::get('/user/{id}/{name}', function (string $id, string $name) {
    // ...
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
为方便起见,一些常用的正则表达式模式具有帮助方法,可让你快速将模式约束添加到路由:
Route::get('/user/{id}/{name}', function (string $id, string $name) {
    // ...
})->whereNumber('id')->whereAlpha('name');
Route::get('/user/{name}', function (string $name) {
    // ...
})->whereAlphaNumeric('name');
Route::get('/user/{id}', function (string $id) {
    // ...
})->whereUuid('id');
Route::get('/user/{id}', function (string $id) {
    //
})->whereUlid('id');
Route::get('/category/{category}', function (string $category) {
    // ...
})->whereIn('category', ['movie', 'song', 'painting']);
如果传入请求与路由模式约束不匹配,将返回 404 HTTP 响应。
全局约束
如果你希望路由参数始终受给定正则表达式的约束,你可以使用 pattern 方法。 你应该在 App\Providers\RouteServiceProvider 类的 boot 方法中定义这些模式:
/**
 * 定义路由模型绑定、模式筛选器等。
 */
public function boot(): void
{
    Route::pattern('id', '[0-9]+');
}
一旦定义了模式,它就会自动应用到使用该参数名称的所有路由:
Route::get('/user/{id}', function (string $id) {
    // 仅当 {id}  是数字时执行。。。
});
编码正斜杠
Laravel 路由组件允许除 / 之外的所有字符出现在路由参数值中。 你必须使用 where 条件正则表达式明确允许 / 成为占位符的一部分:
Route::get('/search/{search}', function (string $search) {
    return $search;
})->where('search', '.*');
注意:仅在最后一个路由段中支持编码的正斜杠。
命名路由
命名路由允许为特定路由方便地生成 URL 或重定向。通过将 name 方法链接到路由定义上,可以指定路由的名称:
Route::get('/user/profile', function () {
    // ...
})->name('profile');