Skip to content

Laravel - 路由

最基本的 Laravel 路由仅接受一个 URI 和一个闭包(Closure),提供了一种非常简单和富有表现力的方式来定义路由:

所有 Laravel 路由都定义在您的路由文件中,这些文件位于 routes 目录中。这些文件由框架自动加载。routes/web.php 文件定义了用于您的 Web 界面的路由。这些路由被分配给 web 中间件(middleware)组,该组提供了会话状态(session state)和 CSRF 保护等功能。routes/api.php 中的路由是无状态的,并被分配给 api 中间件组。

对于大多数应用程序,您将首先在 routes/web.php 文件中定义路由。

默认的 routes/web.php 文件可能看起来像这样:

use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});

这个路由定义了对于根 URL(/)的 GET 请求,Laravel 应该执行提供的闭包。该闭包返回 welcome 视图,该视图通常对应于 resources/views/welcome.blade.php。

路由器允许您注册响应任何 HTTP 动词(verb)的路由:

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 () {
//
});

显示 Laravel 默认欢迎页的过程包含以下步骤:

  • 步骤 1: 用户导航到您的应用程序的根 URL(例如,http://localhost:8000/)。
  • 步骤 2: Laravel 的路由器检查 routes/web.php 文件中是否存在匹配的路由。它找到了 Route::get('/', ...);。
  • 步骤 3: 执行与此路由关联的闭包:function () { return view('welcome'); }。
  • 步骤 4: view('welcome') 函数告诉 Laravel 渲染位于 resources/views/welcome.blade.php 的 Blade 模板。
  • 步骤 5: Laravel 处理这个 Blade 文件,将其编译成纯 PHP,然后编译成 HTML,并发送回用户的浏览器。
  • 步骤 6: 浏览器显示默认的 Laravel 欢迎页,通常在中心位置用大号文本显示 ‘Laravel’。

指向在 web 路由文件中定义的 POST, PUT, PATCH, 或 DELETE 路由的任何 HTML 表单都应包含一个 CSRF token 字段。否则,请求将被拒绝。您可以在 CSRF 文档 中阅读更多关于 CSRF 保护的信息。

<form method="POST" action="/profile">
@csrf
...
</form>

有时您需要在路由中捕获 URI 的片段。例如,您可能需要从 URL 中捕获用户的 ID。您可以通过定义路由参数来实现:

路由参数总是包含在 {} 大括号内,并且应该由字母组成。路由参数根据其顺序注入到路由闭包/控制器中。

Route::get('/user/{id}', function ($id) {
return 'User ID: ' . $id;
});

如果您访问 http://localhost:8000/user/5,输出将是 ‘User ID: 5’。值 5 从 URL 中捕获并作为 $id 传递给闭包。

有时您可能需要指定一个在 URI 中可能不会总是存在的路由参数。您可以通过在参数名后面加上 ? 标记来实现。请确保为路由对应的变量提供一个默认值:

Route::get('/user/{name?}', function ($name = null) {
return 'Username: ' . ($name ?? 'Guest');
});
Route::get('/posts/{post}/comments/{comment?}', function ($postId, $commentId = null) {
if ($commentId) {
return "Viewing comment {$commentId} for post {$postId}.";
}
return "Viewing all comments for post {$postId}.";
});

让我们用一些示例更新 routes/web.php:

routes/web.php

<?php
use Illuminate\Support\Facades\Route;
// Default welcome page route
Route::get('/', function () {
return view('welcome');
});
// Route with a required ID parameter
Route::get('/product/{id}', function ($id) {
return 'Product ID: ' . htmlspecialchars($id);
});
// Route with an optional name parameter
Route::get('/greet/{name?}', function ($name = 'Visitor') {
return 'Hello, ' . htmlspecialchars($name) . '!';
});

测试这些路由:

  • 访问 http://localhost:8000/:浏览器将显示默认的 Laravel 欢迎页。
  • 访问 http://localhost:8000/product/123:浏览器将显示 ‘Product ID: 123’。
  • 访问 http://localhost:8000/greet/John:浏览器将显示 ‘Hello, John!’。
  • 访问 http://localhost:8000/greet/:浏览器将显示 ‘Hello, Visitor!’,因为 name 参数是可选的,并默认为 ‘Visitor’。

您可以使用路由实例上的 where 方法来约束路由参数的格式。where 方法接受参数的名称以及定义如何约束该参数的正则表达式:

Route::get('/user/{name}', function ($name) {
//
})->where('name', '[A-Za-z]+');
Route::get('/user/{id}', function ($id) {
//
})->where('id', '[0-9]+');
Route::get('/user/{id}/{name}', function ($id, $name) {
//
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

有关更高级的路由主题,包括命名路由(Named Routes)、路由组(Route Groups)、路由模型绑定(Route Model Binding)和速率限制(Rate Limiting),请参阅官方 Laravel 文档中关于路由的部分。