路由参数 #
一、必选参数 #
1.1 基本用法 #
php
use Illuminate\Support\Facades\Route;
Route::get('/users/{id}', function ($id) {
return "用户ID: {$id}";
});
1.2 多个参数 #
php
Route::get('/posts/{postId}/comments/{commentId}', function ($postId, $commentId) {
return "文章 {$postId} 的评论 {$commentId}";
});
1.3 参数命名规范 #
php
// 推荐:使用有意义的参数名
Route::get('/users/{user}', function ($user) {
return $user;
});
// 不推荐:使用无意义的名称
Route::get('/users/{id}', function ($id) {
return $id;
});
1.4 参数顺序 #
参数顺序必须与URL中的顺序一致:
php
// 正确
Route::get('/users/{userId}/posts/{postId}', function ($userId, $postId) {
return "用户 {$userId} 的文章 {$postId}";
});
// 错误:参数顺序不匹配
Route::get('/users/{userId}/posts/{postId}', function ($postId, $userId) {
// $postId 实际是 userId 的值
});
二、可选参数 #
2.1 基本用法 #
php
Route::get('/users/{id?}', function ($id = null) {
if ($id) {
return "用户ID: {$id}";
}
return '所有用户';
});
2.2 默认值 #
php
Route::get('/users/{name?}', function ($name = 'Guest') {
return "欢迎, {$name}!";
});
2.3 可选参数位置 #
可选参数必须放在路由末尾:
php
// 正确
Route::get('/posts/{id}/{slug?}', function ($id, $slug = null) {
return "文章 {$id}";
});
// 错误:可选参数不能在必选参数前面
Route::get('/posts/{slug?}/{id}', function ($slug = null, $id) {
// 这会导致错误
});
三、参数约束 #
3.1 where方法 #
使用正则表达式约束参数:
php
// 约束为数字
Route::get('/users/{id}', function ($id) {
return "用户ID: {$id}";
})->where('id', '[0-9]+');
// 约束为字母
Route::get('/users/{name}', function ($name) {
return "用户名: {$name}";
})->where('name', '[a-zA-Z]+');
// 约束为字母和数字
Route::get('/posts/{slug}', function ($slug) {
return "文章别名: {$slug}";
})->where('slug', '[a-zA-Z0-9\-]+');
3.2 多个约束 #
php
Route::get('/posts/{id}/{slug}', function ($id, $slug) {
return "文章 {$id}: {$slug}";
})->where([
'id' => '[0-9]+',
'slug' => '[a-zA-Z0-9\-]+'
]);
3.3 常用约束正则 #
| 约束类型 | 正则表达式 | 说明 |
|---|---|---|
| 数字 | [0-9]+ 或 \d+ |
只匹配数字 |
| 字母 | [a-zA-Z]+ |
只匹配字母 |
| 字母数字 | [a-zA-Z0-9]+ |
匹配字母和数字 |
| Slug | [a-zA-Z0-9\-_]+ |
URL友好的字符串 |
| UUID | [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} |
UUID格式 |
3.4 约束助手方法 #
Laravel提供了便捷的约束方法:
php
// 数字约束
Route::get('/users/{id}', function ($id) {
return $id;
})->whereNumber('id');
// 字母约束
Route::get('/users/{name}', function ($name) {
return $name;
})->whereAlpha('name');
// 字母数字约束
Route::get('/users/{username}', function ($username) {
return $username;
})->whereAlphaNumeric('username');
// UUID约束
Route::get('/users/{uuid}', function ($uuid) {
return $uuid;
})->whereUuid('uuid');
// ULID约束
Route::get('/posts/{ulid}', function ($ulid) {
return $ulid;
})->whereUlid('ulid');
3.5 全局约束 #
在 RouteServiceProvider 中定义全局约束:
php
// app/Providers/RouteServiceProvider.php
public function boot()
{
// 所有 {id} 参数必须是数字
Route::pattern('id', '[0-9]+');
// 所有 {slug} 参数必须是字母数字
Route::pattern('slug', '[a-z0-9-]+');
parent::boot();
}
四、参数编码 #
4.1 编码斜杠 #
默认情况下,参数中不能包含斜杠:
php
// 默认不支持
// /search/category/subcategory
Route::get('/search/{query}', function ($query) {
return $query;
});
允许斜杠:
php
Route::get('/search/{query}', function ($query) {
return $query;
})->where('query', '.*');
4.2 编码特殊字符 #
php
// 空格会被编码为 %20
Route::get('/search/{keyword}', function ($keyword) {
return "搜索: {$keyword}";
});
// 访问 /search/hello%20world
// $keyword = "hello world"
五、访问路由参数 #
5.1 在闭包中访问 #
php
Route::get('/users/{id}', function ($id) {
return $id;
});
5.2 在控制器中访问 #
php
// 控制器方法自动注入参数
class UserController extends Controller
{
public function show($id)
{
return "用户ID: {$id}";
}
}
5.3 通过Request对象访问 #
php
use Illuminate\Http\Request;
Route::get('/users/{id}', function (Request $request) {
$id = $request->route('id');
return $id;
});
// 获取所有参数
Route::get('/posts/{postId}/comments/{commentId}', function (Request $request) {
$params = $request->route()->parameters();
// ['postId' => 1, 'commentId' => 2]
});
5.4 在中间件中访问 #
php
// app/Http/Middleware/CheckPostOwner.php
public function handle($request, Closure $next)
{
$postId = $request->route('post');
// 检查权限
return $next($request);
}
六、高级用法 #
6.1 参数默认值 #
php
Route::get('/category/{category?}', function ($category = 'all') {
return "分类: {$category}";
});
6.2 参数转换 #
php
Route::get('/users/{id}', function ($id) {
// 强制类型转换
$id = (int) $id;
return $id;
});
6.3 参数验证 #
php
Route::get('/users/{id}', function ($id) {
if (!is_numeric($id) || $id <= 0) {
abort(404);
}
return "用户ID: {$id}";
});
七、路由参数与模型绑定 #
7.1 隐式绑定 #
php
use App\Models\User;
Route::get('/users/{user}', function (User $user) {
return $user;
});
// 访问 /users/1
// 自动查询 id=1 的用户
7.2 自定义键名 #
php
Route::get('/users/{user:slug}', function (User $user) {
return $user;
});
// 访问 /users/john
// 自动查询 slug='john' 的用户
7.3 显式绑定 #
php
// RouteServiceProvider 中定义
public function boot()
{
parent::boot();
Route::model('user', User::class);
}
// 路由中使用
Route::get('/users/{user}', function (User $user) {
return $user;
});
八、参数与URL生成 #
8.1 生成带参数的URL #
php
Route::get('/users/{id}', function ($id) {
return $id;
})->name('users.show');
// 生成URL
$url = route('users.show', ['id' => 1]);
// http://example.com/users/1
8.2 多个参数 #
php
Route::get('/posts/{postId}/comments/{commentId}', function ($postId, $commentId) {
return [$postId, $commentId];
})->name('comments.show');
$url = route('comments.show', ['postId' => 1, 'commentId' => 5]);
// http://example.com/posts/1/comments/5
8.3 额外查询参数 #
php
$url = route('users.show', ['id' => 1, 'tab' => 'profile']);
// http://example.com/users/1?tab=profile
九、参数约束最佳实践 #
9.1 使用语义化约束 #
php
// 好的做法
Route::get('/users/{id}', function ($id) {
return $id;
})->whereNumber('id');
// 避免
Route::get('/users/{id}', function ($id) {
return $id;
})->where('id', '[0-9]+');
9.2 约束复用 #
php
// 定义公共约束
Route::pattern('id', '[0-9]+');
Route::pattern('slug', '[a-z0-9-]+');
// 自动应用
Route::get('/users/{id}', function ($id) {
return $id;
});
Route::get('/posts/{slug}', function ($slug) {
return $slug;
});
9.3 约束与验证分离 #
php
// 路由约束:确保格式正确
Route::get('/users/{id}', function ($id) {
return $id;
})->whereNumber('id');
// 控制器验证:确保业务逻辑正确
public function show($id)
{
$user = User::findOrFail($id);
return view('users.show', compact('user'));
}
十、常见问题 #
10.1 参数匹配顺序 #
php
// 正确:更具体的路由在前
Route::get('/users/create', function () {
return '创建用户表单';
});
Route::get('/users/{id}', function ($id) {
return "用户ID: {$id}";
});
// 错误:顺序颠倒会导致 /users/create 匹配到 {id}
10.2 可选参数与默认值 #
php
// 正确
Route::get('/users/{status?}', function ($status = 'active') {
return $status;
});
// 访问 /users -> active
// 访问 /users/inactive -> inactive
10.3 参数命名冲突 #
php
// 避免:同名参数在不同路由中含义不同
Route::get('/users/{id}', ...); // 用户ID
Route::get('/posts/{id}', ...); // 文章ID
// 推荐:使用语义化命名
Route::get('/users/{userId}', ...);
Route::get('/posts/{postId}', ...);
十一、总结 #
11.1 核心要点 #
| 要点 | 说明 |
|---|---|
| 必选参数 | {param} 格式 |
| 可选参数 | {param?} 格式,需默认值 |
| 参数约束 | where() 方法或全局 pattern() |
| 约束助手 | whereNumber, whereAlpha 等 |
| 模型绑定 | 自动解析模型实例 |
11.2 下一步 #
掌握了路由参数后,让我们继续学习 路由组与中间件,了解如何组织复杂路由!
最后更新:2026-03-28