路由
基础路由
最基础的 Laravel 路由接受一个 URI 和一个闭包,提供一种非常简单且富有表现力的方式来定义路由与行为,而无需复杂的路由配置文件:
use Illuminate\Support\Facades\Route;
Route::get('/greeting', function () {
return 'Hello World';
});
默认路由文件
所有 Laravel 路由都定义在位于 routes 目录下的路由文件中。Laravel 会根据应用 bootstrap/app.php 文件中指定的配置自动加载这些文件。routes/web.php 文件定义用于 Web 界面的路由。这些路由会被分配到 web 中间件组,该组提供会话状态与 CSRF 保护等功能。
对大多数应用而言,你会先在 routes/web.php 文件中定义路由。在 routes/web.php 中定义的路由可通过在浏览器中输入已定义路由的 URL 访问。例如,可在浏览器中访问 http://example.com/user 来访问以下路由:
use App\Http\Controllers\UserController;
Route::get('/user', [UserController::class, 'index']);
API 路由
若应用还将提供无状态 API,可使用 install:api Artisan 命令启用 API 路由:
php artisan install:apiinstall:api 命令会安装 Laravel Sanctum,它提供强大且简单的 API 令牌认证守卫,可用于认证第三方 API 消费者、SPA 或移动应用。此外,该命令还会创建 routes/api.php 文件:
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
routes/api.php 中的路由是无状态的,并被分配到 api 中间件组。此外,这些路由会自动应用 /api URI 前缀,因此无需在文件中为每条路由手动添加。可通过修改应用的 bootstrap/app.php 文件更改此前缀:
->withRouting(
api: __DIR__.'/../routes/api.php',
apiPrefix: 'api/admin',
// ...
)
可用的路由器方法
路由器允许你注册响应任意 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 () {
// ...
});
INFO
定义共享同一 URI 的多条路由时,使用 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 保护
请记住,任何指向在 web 路由文件中定义的 POST、PUT、PATCH 或 DELETE 路由的 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');
WARNING
在重定向路由中使用路由参数时,以下参数由 Laravel 保留且不能使用:destination 与 status。
视图路由
若路由只需返回一个视图,可使用 Route::view 方法。与 redirect 方法类似,该方法提供简单快捷方式,使你无需定义完整路由或控制器。view 方法的第一个参数为 URI,第二个参数为视图名称。此外,可将传给视图的数据数组作为可选的第三个参数:
Route::view('/welcome', 'welcome');
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
WARNING
在视图路由中使用路由参数时,以下参数由 Laravel 保留且不能使用:view、data、status 与 headers。
列出你的路由
route:list Artisan 命令可轻松提供应用中定义的所有路由的概览:
php artisan route:list默认情况下,分配给每条路由的路由中间件不会显示在 route:list 输出中;不过,可通过向命令添加 -v 选项,指示 Laravel 显示路由中间件与中间件组名称:
php artisan route:list -v
# Expand middleware groups...
php artisan route:list -vv也可指示 Laravel 仅显示以给定 URI 开头的路由:
php artisan route:list --path=api此外,执行 route:list 命令时可提供 --except-vendor 选项,指示 Laravel 隐藏由第三方包定义的任何路由:
php artisan route:list --except-vendor同样,执行 route:list 命令时可提供 --only-vendor 选项,指示 Laravel 仅显示由第三方包定义的路由:
php artisan route:list --only-vendor路由自定义
默认情况下,应用的路由由 bootstrap/app.php 文件配置并加载:
<?php
use Illuminate\Foundation\Application;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)->create();不过,有时你可能希望定义一个全新文件来存放应用路由的子集。为此,可向 withRouting 方法提供 then 闭包。在该闭包内,可注册应用所需的任何额外路由:
use Illuminate\Support\Facades\Route;
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
then: function () {
Route::middleware('api')
->prefix('webhooks')
->name('webhooks.')
->group(base_path('routes/webhooks.php'));
},
)或者,甚至可通过向 withRouting 方法提供 using 闭包来完全控制路由注册。传入该参数时,框架不会注册任何 HTTP 路由,你需负责手动注册所有路由:
use Illuminate\Support\Facades\Route;
->withRouting(
commands: __DIR__.'/../routes/console.php',
using: function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));
Route::middleware('web')
->group(base_path('routes/web.php'));
},
)路由参数
必填参数
有时你需要在路由中捕获 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;
});
可选参数
偶尔你需要指定一个不一定总是出现在 URI 中的路由参数。可在参数名后放置 ? 标记。请确保为路由对应的变量提供默认值:
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']);
Route::get('/category/{category}', function (string $category) {
// ...
})->whereIn('category', CategoryEnum::cases());
若传入请求不匹配路由模式约束,将返回 404 HTTP 响应。
全局约束
若希望路由参数始终受给定正则表达式约束,可使用 pattern 方法。应在应用的 App\Providers\AppServiceProvider 类的 boot 方法中定义这些模式:
use Illuminate\Support\Facades\Route;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Route::pattern('id', '[0-9]+');
}一旦定义了模式,它会自动应用于使用该参数名的所有路由:
Route::get('/user/{id}', function (string $id) {
// Only executed if {id} is numeric...
});
编码的正斜杠
Laravel 路由组件允许路由参数值中出现除 / 以外的所有字符。必须使用 where 条件正则表达式显式允许 / 成为占位符的一部分:
Route::get('/search/{search}', function (string $search) {
return $search;
})->where('search', '.*');
WARNING
编码的正斜杠仅在最后一个路由段中受支持。
命名路由
命名路由允许方便地为特定路由生成 URL 或重定向。可通过在路由定义上链式调用 name 方法为路由指定名称:
Route::get('/user/profile', function () {
// ...
})->name('profile');
也可为控制器动作指定路由名称:
Route::get(
'/user/profile',
[UserProfileController::class, 'show']
)->name('profile');
WARNING
路由名称应始终唯一。
生成命名路由的 URL
为给定路由分配名称后,可通过 Laravel 的 route 与 redirect 辅助函数,在生成 URL 或重定向时使用该路由名称:
// Generating URLs...
$url = route('profile');
// Generating Redirects...
return redirect()->route('profile');
return to_route('profile');
若命名路由定义了参数,可将参数作为 route 函数的第二个参数传入。给定参数会自动插入到生成的 URL 的正确位置:
Route::get('/user/{id}/profile', function (string $id) {
// ...
})->name('profile');
$url = route('profile', ['id' => 1]);
若在数组中传入额外参数,这些键 / 值对会自动添加到生成的 URL 的查询字符串中:
Route::get('/user/{id}/profile', function (string $id) {
// ...
})->name('profile');
$url = route('profile', ['id' => 1, 'photos' => 'yes']);
// /user/1/profile?photos=yes
INFO
有时你可能希望为 URL 参数指定请求范围内的默认值,例如当前语言环境。为此,可使用 URL::defaults 方法。
检查当前路由
若希望判断当前请求是否路由到给定命名路由,可在 Route 实例上使用 named 方法。例如,可从路由中间件中检查当前路由名称:
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if ($request->route()->named('profile')) {
// ...
}
return $next($request);
}路由组
路由组允许你在大量路由之间共享路由属性(如中间件),而无需在每条单独路由上定义这些属性。
嵌套组会尝试智能地与父组「合并」属性。中间件与 where 条件会合并,而名称与前缀会追加。URI 前缀中的命名空间分隔符与斜杠会在适当处自动添加。
中间件
要为组内所有路由分配中间件,可在定义组之前使用 middleware 方法。中间件按数组中列出的顺序执行:
Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// Uses first & second middleware...
});
Route::get('/user/profile', function () {
// Uses first & second middleware...
});
});
控制器
若一组路由都使用同一控制器,可使用 controller 方法为组内所有路由定义公共控制器。然后在定义路由时,只需提供它们调用的控制器方法:
use App\Http\Controllers\OrderController;
Route::controller(OrderController::class)->group(function () {
Route::get('/orders/{id}', 'show');
Route::post('/orders', 'store');
});
子域名路由
路由组也可用于处理子域名路由。子域名可像路由 URI 一样分配路由参数,从而捕获子域名的一部分供路由或控制器使用。可在定义组之前调用 domain 方法指定子域名:
Route::domain('{account}.example.com')->group(function () {
Route::get('/user/{id}', function (string $account, string $id) {
// ...
});
});
WARNING
为确保子域名路由可被访问,应在注册根域名路由之前先注册子域名路由。这样可防止根域名路由覆盖具有相同 URI 路径的子域名路由。
路由前缀
prefix 方法可用于为组内每条路由加上给定 URI 前缀。例如,你可能希望为组内所有路由 URI 加上 admin 前缀:
Route::prefix('admin')->group(function () {
Route::get('/users', function () {
// Matches The "/admin/users" URL
});
});
路由名称前缀
name 方法可用于为组内每条路由名称加上给定字符串前缀。例如,你可能希望为组内所有路由名称加上 admin 前缀。给定字符串会按原样加在路由名称前,因此我们会确保在前缀中提供末尾的 . 字符:
Route::name('admin.')->group(function () {
Route::get('/users', function () {
// Route assigned name "admin.users"...
})->name('users');
});
路由模型绑定
向路由或控制器动作注入模型 ID 时,你经常需要查询数据库以检索对应该 ID 的模型。Laravel 路由模型绑定提供了一种便捷方式,可将模型实例自动直接注入到路由中。例如,不必注入用户 ID,而可注入与给定 ID 匹配的整个 User 模型实例。
隐式绑定
Laravel 会自动解析在路由或控制器动作中定义的 Eloquent 模型,前提是其类型提示的变量名与路由段名称匹配。例如:
use App\Models\User;
Route::get('/users/{user}', function (User $user) {
return $user->email;
});
由于 $user 变量被类型提示为 App\Models\User Eloquent 模型,且变量名与 {user} URI 段匹配,Laravel 会自动注入 ID 与请求 URI 中对应值匹配的模型实例。若在数据库中未找到匹配的模型实例,将自动生成 404 HTTP 响应。
当然,使用控制器方法时也可进行隐式绑定。同样请注意,{user} URI 段与控制器中包含 App\Models\User 类型提示的 $user 变量匹配:
use App\Http\Controllers\UserController;
use App\Models\User;
// Route definition...
Route::get('/users/{user}', [UserController::class, 'show']);
// Controller method definition...
public function show(User $user)
{
return view('user.profile', ['user' => $user]);
}
软删除模型
通常,隐式模型绑定不会检索已被软删除的模型。不过,可通过在路由定义上链式调用 withTrashed 方法,指示隐式绑定检索这些模型:
use App\Models\User;
Route::get('/users/{user}', function (User $user) {
return $user->email;
})->withTrashed();
自定义键
有时你可能希望使用 id 以外的列来解析 Eloquent 模型。为此,可在路由参数定义中指定该列:
use App\Models\Post;
Route::get('/posts/{post:slug}', function (Post $post) {
return $post;
});
若希望模型绑定在检索给定模型类时始终使用 id 以外的数据库列,可在 Eloquent 模型上重写 getRouteKeyName 方法:
/**
* Get the route key for the model.
*/
public function getRouteKeyName(): string
{
return 'slug';
}自定义键与作用域
在单个路由定义中隐式绑定多个 Eloquent 模型时,你可能希望对第二个 Eloquent 模型施加作用域,使其必须是前一个 Eloquent 模型的子模型。例如,考虑这个按 slug 为特定用户检索博客文章的路由定义:
use App\Models\Post;
use App\Models\User;
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
return $post;
});
将自定义键的隐式绑定用作嵌套路由参数时,Laravel 会自动按约定猜测父模型上的关联名称,并将查询限定为通过父模型检索嵌套模型。在本例中,会假定 User 模型有一个名为 posts(路由参数名的复数形式)的关联,可用于检索 Post 模型。
若需要,即使未提供自定义键,也可指示 Laravel 对「子」绑定施加作用域。为此,可在定义路由时调用 scopeBindings 方法:
use App\Models\Post;
use App\Models\User;
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
return $post;
})->scopeBindings();
或者,可指示一整组路由定义使用作用域绑定:
Route::scopeBindings()->group(function () {
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
return $post;
});
});
同样,可通过调用 withoutScopedBindings 方法显式指示 Laravel 不施加作用域绑定:
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
return $post;
})->withoutScopedBindings();
自定义模型缺失行为
通常,若找不到隐式绑定的模型,将生成 404 HTTP 响应。不过,可在定义路由时调用 missing 方法自定义此行为。missing 方法接受一个闭包,在无法找到隐式绑定模型时调用:
use App\Http\Controllers\LocationsController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
Route::get('/locations/{location:slug}', [LocationsController::class, 'show'])
->name('locations.view')
->missing(function (Request $request) {
return Redirect::route('locations.index');
});
隐式枚举绑定
PHP 8.1 引入了对 Enums 的支持。为配合此特性,Laravel 允许你在路由定义上类型提示字符串后备 Enum;仅当该路由段对应有效 Enum 值时,Laravel 才会调用该路由。否则将自动返回 404 HTTP 响应。例如,给定如下 Enum:
<?php
namespace App\Enums;
enum Category: string
{
case Fruits = 'fruits';
case People = 'people';
}可定义一条仅在 {category} 路由段为 fruits 或 people 时才会被调用的路由。否则 Laravel 将返回 404 HTTP 响应:
use App\Enums\Category;
use Illuminate\Support\Facades\Route;
Route::get('/categories/{category}', function (Category $category) {
return $category->value;
});显式绑定
使用模型绑定并不要求使用 Laravel 基于约定的隐式模型解析。也可显式定义路由参数如何对应模型。要注册显式绑定,使用路由器的 model 方法为给定参数指定类。应在 AppServiceProvider 类的 boot 方法开头定义显式模型绑定:
use App\Models\User;
use Illuminate\Support\Facades\Route;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Route::model('user', User::class);
}接下来,定义一条包含 {user} 参数的路由:
use App\Models\User;
Route::get('/users/{user}', function (User $user) {
// ...
});
由于我们将所有 {user} 参数绑定到了 App\Models\User 模型,该类的实例会被注入到路由中。因此,例如对 users/1 的请求会注入数据库中 ID 为 1 的 User 实例。
若在数据库中未找到匹配的模型实例,将自动生成 404 HTTP 响应。
自定义解析逻辑
若希望定义自己的模型绑定解析逻辑,可使用 Route::bind 方法。传给 bind 方法的闭包会接收 URI 段的值,并应返回应注入到路由中的类实例。同样,此自定义应在应用的 AppServiceProvider 的 boot 方法中进行:
use App\Models\User;
use Illuminate\Support\Facades\Route;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Route::bind('user', function (string $value) {
return User::where('name', $value)->firstOrFail();
});
}或者,可在 Eloquent 模型上覆盖 resolveRouteBinding 方法。该方法会接收 URI 段的值,并应返回应注入到路由中的类实例:
/**
* Retrieve the model for a bound value.
*
* @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();
}若路由使用了隐式绑定作用域,将使用 resolveChildRouteBinding 方法解析父模型的子绑定:
/**
* Retrieve the child model for a bound value.
*
* @param string $childType
* @param mixed $value
* @param string|null $field
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function resolveChildRouteBinding($childType, $value, $field)
{
return parent::resolveChildRouteBinding($childType, $value, $field);
}兜底路由
使用 Route::fallback 方法,可定义一条在没有任何其他路由匹配传入请求时执行的路由。通常,未处理的请求会通过应用的异常处理器自动渲染「404」页面。不过,由于通常会在 routes/web.php 文件中定义 fallback 路由,web 中间件组中的所有中间件都会应用于该路由。你可根据需要向此路由添加额外中间件:
Route::fallback(function () {
// ...
});
速率限制
定义速率限制器
Laravel 包含强大且可自定义的速率限制服务,可用于限制给定路由或路由组的流量。开始时,应定义满足应用需求的速率限制器配置。
速率限制器可在应用的 App\Providers\AppServiceProvider 类的 boot 方法中定义:
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
/**
* Bootstrap any application services.
*/
protected function boot(): void
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
}速率限制器使用 RateLimiter facade 的 for 方法定义。for 方法接受速率限制器名称,以及返回应应用于分配给该速率限制器的路由的限制配置的闭包。限制配置是 Illuminate\Cache\RateLimiting\Limit 类的实例。该类包含有用的「构建器」方法,便于快速定义限制。速率限制器名称可以是任意字符串:
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
/**
* Bootstrap any application services.
*/
protected function boot(): void
{
RateLimiter::for('global', function (Request $request) {
return Limit::perMinute(1000);
});
}若传入请求超过指定速率限制,Laravel 会自动返回 429 HTTP 状态码的响应。若希望定义速率限制应返回的自定义响应,可使用 response 方法:
RateLimiter::for('global', function (Request $request) {
return Limit::perMinute(1000)->response(function (Request $request, array $headers) {
return response('Custom response...', 429, $headers);
});
});
由于速率限制器回调会接收传入的 HTTP 请求实例,你可根据传入请求或已认证用户动态构建适当的速率限制:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()
? Limit::none()
: Limit::perMinute(100);
});
分割速率限制
有时你可能希望按某个任意值分割速率限制。例如,你可能希望允许用户按每个 IP 地址每分钟访问给定路由 100 次。为此,可在构建速率限制时使用 by 方法:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()
? Limit::none()
: Limit::perMinute(100)->by($request->ip());
});
再用另一个例子说明此功能:我们可以将路由访问限制为每个已认证用户 ID 每分钟 100 次,或对访客按每个 IP 地址每分钟 10 次:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()
? Limit::perMinute(100)->by($request->user()->id)
: Limit::perMinute(10)->by($request->ip());
});
多个速率限制
如有需要,可为给定速率限制器配置返回速率限制数组。每个速率限制会按它们在数组中的顺序对路由进行评估:
RateLimiter::for('login', function (Request $request) {
return [
Limit::perMinute(500),
Limit::perMinute(3)->by($request->input('email')),
];
});
若分配了多个按相同 by 值分割的速率限制,应确保每个 by 值唯一。最简单的方法是为传给 by 方法的值添加前缀:
RateLimiter::for('uploads', function (Request $request) {
return [
Limit::perMinute(10)->by('minute:'.$request->user()->id),
Limit::perDay(1000)->by('day:'.$request->user()->id),
];
});
将速率限制器附加到路由
可使用 throttle 中间件将速率限制器附加到路由或路由组。throttle 中间件接受你希望分配给路由的速率限制器名称:
Route::middleware(['throttle:uploads'])->group(function () {
Route::post('/audio', function () {
// ...
});
Route::post('/video', function () {
// ...
});
});
使用 Redis 进行节流
默认情况下,throttle 中间件映射到 Illuminate\Routing\Middleware\ThrottleRequests 类。不过,若使用 Redis 作为应用的缓存驱动,你可能希望指示 Laravel 使用 Redis 管理速率限制。为此,应在应用的 bootstrap/app.php 文件中使用 throttleWithRedis 方法。该方法将 throttle 中间件映射到 Illuminate\Routing\Middleware\ThrottleRequestsWithRedis 中间件类:
->withMiddleware(function (Middleware $middleware) {
$middleware->throttleWithRedis();
// ...
})
表单方法伪造
HTML 表单不支持 PUT、PATCH 或 DELETE 动作。因此,定义从 HTML 表单调用的 PUT、PATCH 或 DELETE 路由时,需要向表单添加隐藏的 _method 字段。与 _method 字段一起发送的值将用作 HTTP 请求方法:
<form action="/example" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
为方便起见,可使用 @method Blade 指令生成 _method 输入字段:
<form action="/example" method="POST">
@method('PUT')
@csrf
</form>
访问当前路由
可在 Route facade 上使用 current、currentRouteName 与 currentRouteAction 方法,访问处理传入请求的路由信息:
use Illuminate\Support\Facades\Route;
$route = Route::current(); // Illuminate\Routing\Route
$name = Route::currentRouteName(); // string
$action = Route::currentRouteAction(); // string
可参阅 Route facade 底层类与 Route 实例的 API 文档,查看路由器与路由类上可用的所有方法。
跨源资源共享(CORS)
Laravel 可用你配置的值自动响应 CORS OPTIONS HTTP 请求。OPTIONS 请求会由自动包含在应用全局中间件栈中的 HandleCors 中间件自动处理。
有时你可能需要自定义应用的 CORS 配置值。可使用 config:publish Artisan 命令发布 cors 配置文件来完成:
php artisan config:publish cors该命令会在应用的 config 目录中放置 cors.php 配置文件。
INFO
有关 CORS 与 CORS 头的更多信息,请参阅 MDN 关于 CORS 的 Web 文档。
路由缓存
将应用部署到生产环境时,应利用 Laravel 的路由缓存。使用路由缓存会大幅减少注册应用所有路由所需的时间。要生成路由缓存,执行 route:cache Artisan 命令:
php artisan route:cache运行此命令后,缓存的路由文件会在每次请求时加载。请记住,若添加任何新路由,需要重新生成路由缓存。因此,应仅在项目部署期间运行 route:cache 命令。
可使用 route:clear 命令清除路由缓存:
php artisan route:clear