掌握 Laravel 路由

已发表: 2022-12-12

说到后端,开发者最终都会遇到路由。 路由可以被认为是后端的骨干,因为服务器收到的每个请求都通过将请求映射到控制器或操作的路由列表重定向到控制器。

Laravel 为我们隐藏了许多实现细节,并附带了大量语法糖来帮助新手和有经验的开发人员开发他们的 Web 应用程序。

让我们仔细看看如何在 Laravel 中管理路由。

Laravel 中的后端路由和跨站脚本

在一台服务器上,既有公有路由,也有私有路由。 由于跨站点脚本 (XSS) 的可能性,公共路由可能引起关注,这是一种注入攻击,可能使您和您的用户容易受到恶意行为者的攻击。

问题在于,用户可以从不需要会话令牌的路由重定向到需要会话令牌的路由——他们仍然可以在没有令牌的情况下访问。 点击鸣叫

解决此问题的最简单方法是强制执行新的 HTTP 标头,将“referrer”添加到路由以缓解这种情况:

 'main' => [ 'path' => '/main', 'referrer' => 'required,refresh-empty', 'target' => Controller\DashboardController::class . '::mainAction' ]

Laravel 基本路由

在 Laravel 中,路由允许用户将适当的请求路由到所需的控制器。 最基本的 Laravel 路由接受一个统一资产标识符(你的路由路径)和一个可以是函数或类的闭包。

在 Laravel 中,路由是在web.phpapi.php文件中创建的。 Laravel 默认自带两种路由:一种用于 WEB,一种用于 API。

这些路由位于routes/文件夹中,但它们加载在Providers/RouteServiceProvider.php中。

显示 Laravel 路由服务提供者默认状态的命令行。
Laravel 路由服务提供者的默认状态。

我们可以直接在RouteServiceProvider.php中加载路由,而不是这样做,完全跳过routes/文件夹。

一个命令行窗口,显示直接在提供程序中加载 Laravel 路由。
直接在提供者中加载 Laravel 路由。

重定向

当我们定义一个路由时,我们通常会想要重定向访问它的用户,而这样做的原因多种多样。 这可能是因为它是一个已弃用的路由,我们已经更改了后端或服务器,或者可能是因为我们想要安装双因素身份验证 (2FA),等等。

Laravel 有一个简单的方法可以做到这一点。 由于框架的简单性,我们可以在 Route facade 上使用 redirect 方法,它接受入口路由和要重定向到的路由。

或者,我们可以将重定向的状态代码作为第三个参数。 permanentRedirect方法将与redirect方法做同样的事情,除了它总是返回 301 状态代码:

 // Simple redirect Route::redirect("/class", "/myClass"); // Redirect with custom status Route::redirect("/home", "/office", 305); // Route redirect with 301 status code Route::permanentRedirect("/home", "office");

在重定向路由中,我们禁止使用“destination”和“status”关键字作为参数,因为它们被 Laravel 保留。

 // Illegal to use Route::redirect("/home", "/office/{status}");

观点

意见是。 我们用来呈现 Laravel 应用程序前端的blade.php文件。 它使用 blade 模板引擎,它是仅使用 Laravel 构建全栈应用程序的默认方式。

如果我们希望我们的路由返回一个视图,我们可以简单地使用 Route facade 上的 view 方法。 它接受路由参数、视图名称和要传递给视图的可选值数组。

 // When the user accesses my-domain.com/homepage // the homepage.blade.php file will be rendered Route::view("/homepage", "homepage");

假设我们的视图想通过传递一个带有该参数的可选数组来说“你好, {name} ”。 我们可以使用以下代码来做到这一点(如果视图中需要缺少的参数,请求将失败并抛出错误):

 Route::view('/homepage', 'homepage', ['name' => "Kinsta"]);

路线列表

随着应用程序规模的增长,需要路由的请求数量也会增加。 大量的信息会带来巨大的混乱。

这是artisan route:list command可以帮助我们的地方。 它概述了应用程序中定义的所有路由、它们的中间件和控制器。

 php artisan route:list

它将显示没有中间件的所有路由列表。 为此,我们必须使用-v标志:

 php artisan route:list -v

在您可能使用域驱动设计的情况下,您的路由在其路径中具有特定名称,您可以像这样使用此命令的过滤功能:

 php artisan route:list –path=api/account

这将仅显示以api/account开头的路由。

另一方面,我们可以使用–except-vendor–only-vendor选项指示 Laravel 排除或包含第三方定义的路由。

路由参数

有时您可能需要使用路由捕获 URI 的片段,例如用户 ID 或令牌。 我们可以通过定义一个路由参数来做到这一点,该参数始终包含在花括号 ( {} ) 中并且应该只包含字母字符。

如果我们的路由在回调中有依赖,Laravel 服务容器会自动注入它们:

 use Illuminate\Http\Request; use Controllers/DashboardController; Route::post('/dashboard/{id}, function (Request $request, string $id) { return 'User:' . $id; } Route::get('/dashboard/{id}, DashboardController.php);

必需参数

Laravel 的必参是路由中的参数,我们在调用的时候不允许跳过。 否则,将抛出错误:

 Route::post("/gdpr/{userId}", GetGdprDataController.php");

现在在GetGdprDataController.php中,我们可以直接访问$userId参数。

 public function __invoke(int $userId) { // Use the userId that we received… }

路由可以采用任意数量的参数。 它们根据它们列出的顺序被注入到路由回调/控制器中:

 // api.php Route::post('/gdpr/{userId}/{userName}/{userAge}', GetGdprDataController.php); // GetGdprDataController.php public function __invoke(int $userId, string $userName, int $userAge) { // Use the parameters… }

可选参数

如果我们想在路由上只提供一个参数而没有其他任何东西,而不影响整个应用程序,我们可以添加一个可选参数。 这些可选参数由? 附加到他们:

 Route::get('/user/{age?}', function (int $age = null) { if (!$age) Log::info("User doesn't have age set"); else Log::info("User's age is " . $age); } Route::get('/user/{name?}', function (int $name = "John Doe") { Log::info("User's name is " . $name); }

路由通配符

Laravel 为我们提供了一种方法来过滤我们的可选或必需参数应该是什么样子。

假设我们想要一个用户 ID 字符串。 我们可以使用where方法在路由级别上像这样验证它。

where方法接受参数名称和将应用于验证的正则表达式规则。 默认情况下,它接受第一个参数,但如果我们有很多,我们可以传递一个数组,以参数名称作为键,规则作为值,Laravel 会为我们解析它们:

 Route::get('/user/{age}', function (int $age) { // }->where('age', '[0-9]+'); Route::get('/user/{age}', function (int $age) { // }->where('[0-9]+'); Route::get('/user/{age}/{name}', function (int $age, string $name) { // }->where(['age' => '[0-9]+', 'name' => '[az][Az]+');

我们可以更进一步,通过在Route facade 上使用pattern方法对我们应用程序中的所有路由应用验证:

 Route::pattern('id', '[0-9]+');

这将使用此正则表达式验证每个id参数。 一旦我们定义它,它将自动应用到所有使用该参数名称的路由。

如我们所见,Laravel 使用/字符作为路径中的分隔符。 如果我们想在路径中使用它,我们必须使用where正则表达式明确允许它成为我们占位符的一部分。

 Route::get('/find/{query}', function ($query) { // })->where('query', , '.*');

唯一的缺点是它只会在最后一个路线段中得到支持。

命名路由

顾名思义,我们可以为路由命名,这样可以方便地为特定路由生成 URL 或重定向。

为停机和 WordPress 问题苦苦挣扎? Kinsta 是旨在节省您时间的托管解决方案! 查看我们的功能

如何创建命名路由

链接在Route facade 上的name方法提供了一种创建命名路由的简单方法。 每条路线的名称应该是唯一的:

 Route::get('/', function () { })->name("homepage");

路由组

路由组允许您在大量路由之间共享路由属性(如中间件),而无需在每条路由上重新定义它。

中间件

为我们拥有的所有路由分配一个中间件允许我们将它们组合成一个组,首先使用group方法。 需要考虑的一件事是中间件按照它们应用于组的顺序执行:

 Route:middleware(['AuthMiddleware', 'SessionMiddleware'])->group(function () { Route::get('/', function() {} ); Route::post('/upload-picture', function () {} ); });

控制器

当一个组使用相同的控制器时,我们可以使用controller方法为该组内的所有路由定义公共控制器。 现在我们必须指定路由将调用的方法。

 Route::controller(UserController::class)->group(function () { Route::get('/orders/{userId}', 'getOrders'); Route::post('/order/{id}', 'postOrder'); });

子域路由

子域名是添加到网站域名开头的一段附加信息。 这允许网站为特定功能(例如在线商店、博客、演示文稿等)与网站的其余部分分离和组织其内容。

我们的路由可用于处理子域路由。 我们可以捕获域和子域的一部分,以便在我们的控制器和路由中使用。 在Route facade 上的domain方法的帮助下,我们可以将我们的路由分组在一个域下:

 Route::domain('{store}.enterprise.com')->group(function() { Route::get('order/{id}', function (Account $account, string $id) { // Your Code } });

前缀和名称前缀

每当我们有一组路由时,我们可以利用 Laravel 提供的额外实用程序,例如Route facade 上的prefixname ,而不是一个接一个地修改它们。

prefix方法可用于为组中的每个路由添加给定 URI 前缀, name方法可用于为每个路由名称添加给定字符串前缀。

这允许我们创建新的东西,比如管理路由,而不需要修改每个名称或前缀来识别它们:

 Route::name('admin.")->group(function() { Route::prefix("admin")->group(function() { Route::get('/get')->name('get'); Route::put('/put')->name(put'); Route::post('/post')->name('post'); }); });

现在这些路由的 URI 将是admin/getadmin/putadmin/post以及名称admin.getadmin.putadmin.post

路由缓存

将应用程序部署到生产服务器时,优秀的 Laravel 开发人员会利用 Laravel 的路由缓存。

什么是路由缓存?

路由缓存减少了注册所有应用程序路由所需的时间。

运行php artisan route:cache会生成一个Illuminate/Routing/RouteCollection的实例,经过编码后,序列化后的输出会写入bootstrap/cache.routes.php

现在任何其他请求都将加载此缓存文件(如果存在)。 因此,我们的应用程序不再需要将路由文件中的条目解析并转换为Illuminate/Routing/Route Illuminate/Routing/RouteCollection Route 对象。

为什么使用路由缓存很重要

如果不使用 Laravel 提供的路由缓存功能,您的应用程序可能会运行得比预期的慢,这反过来可能会降低销售额、用户保留率和对您品牌的信任度。

根据项目的规模和路由的数量,运行一个简单的路由缓存命令可以将应用程序的速度提高 130% 到 500%——这是一个几乎不费吹灰之力的巨大收获。

概括

路由是后端开发的支柱。 Laravel 框架在这方面表现出色,它提供了一种定义和管理路由的冗长方式。 在这份详尽的指南中熟悉 Laravel 路由点击推文

确实每个人都可以进行开发,并且仅仅因为它是在 Laravel 中构建的,就可以帮助加速应用程序。

关于 Laravel 路由,你还遇到过哪些其他技巧和技巧? 请在评价部分留下您的意见!