# 如何在 Laravel 中使用路由和中间件?
路由和中间件是 Laravel 框架中两个非常核心的概念,它们共同构成了应用程序的请求处理流程。本文将详细介绍如何在 Laravel 中使用路由和中间件来构建强大的 Web 应用程序。
## 一、Laravel 路由基础
### 1. 基本路由定义
Laravel 的路由定义在 `routes/` 目录下的文件中,最常见的是 `web.php` 和 `api.php`。
```php
// 基本 GET 路由
Route::get('/', function () {
return view('welcome');
});
// 基本 POST 路由
Route::post('user', function () {
// 处理用户创建逻辑
});
```
### 2. 路由参数
```php
// 必选参数
Route::get('user/{id}', function ($id) {
return 'User '.$id;
});
// 可选参数
Route::get('user/{name?}', function ($name = null) {
return $name;
});
// 正则约束
Route::get('user/{id}', function ($id) {
//
})->where('id', '[0-9]+');
```
### 3. 命名路由
```php
Route::get('user/profile', function () {
//
})->name('profile');
```
可以在应用中生成 URL:
```php
$url = route('profile');
```
### 4. 路由组
```php
Route::prefix('admin')->group(function () {
Route::get('users', function () {
// 匹配 "/admin/users" URL
});
});
Route::middleware(['auth'])->group(function () {
Route::get('dashboard', function () {
// 需要认证
});
});
```
## 二、控制器路由
### 1. 基本控制器路由
```php
Route::get('user/{id}', 'UserController@show');
```
对应的控制器:
```php
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
public function show($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
```
### 2. 资源控制器
```php
Route::resource('photos', 'PhotoController');
```
这会自动创建以下路由:
| 请求方法 | URI | 控制器方法 | 路由名称 |
|----------|--------------------|------------|--------------|
| GET | /photos | index | photos.index |
| GET | /photos/create | create | photos.create|
| POST | /photos | store | photos.store |
| GET | /photos/{photo} | show | photos.show |
| GET | /photos/{photo}/edit | edit | photos.edit |
| PUT/PATCH| /photos/{photo} | update | photos.update|
| DELETE | /photos/{photo} | destroy | photos.destroy|
## 三、Laravel 中间件
### 1. 什么是中间件?
中间件提供了一种方便的机制来过滤进入应用的 HTTP 请求。例如,Laravel 包含一个验证用户是否经过身份验证的中间件。如果用户未经过身份验证,中间件会将用户重定向到登录页面。
### 2. 定义中间件
使用 Artisan 命令创建中间件:
```bash
php artisan make:middleware CheckAge
```
这将生成 `app/Http/Middleware/CheckAge.php`:
```php
<?php
namespace App\Http\Middleware;
use Closure;
class CheckAge
{
public function handle($request, Closure $next)
{
if ($request->age <= 200) {
return redirect('home');
}
return $next($request);
}
}
```
### 3. 注册中间件
在 `app/Http/Kernel.php` 中注册中间件:
```php
// 全局中间件
protected $middleware = [
\App\Http\Middleware\CheckForMaintenanceMode::class,
// ...
];
// 路由中间件
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'check.age' => \App\Http\Middleware\CheckAge::class,
// ...
];
```
### 4. 使用中间件
#### 在路由中使用
```php
Route::get('admin/profile', function () {
//
})->middleware('auth');
// 多个中间件
Route::get('/', function () {
//
})->middleware('first', 'second');
```
#### 在控制器中使用
```php
class UserController extends Controller
{
public function __construct()
{
$this->middleware('auth');
// 只对特定方法应用中间件
$this->middleware('log')->only('index');
// 排除特定方法
$this->middleware('subscribed')->except('store');
}
}
```
### 5. 中间件参数
中间件也可以接收额外的参数:
```php
// 定义可接收参数的中间件
public function handle($request, Closure $next, $role)
{
if (! $request->user()->hasRole($role)) {
// 重定向...
}
return $next($request);
}
// 使用带参数的中间件
Route::put('post/{id}', function ($id) {
//
})->middleware('role:editor');
```
## 四、高级路由技巧
### 1. 路由模型绑定
```php
Route::get('api/users/{user}', function (App\User $user) {
return $user->email;
});
```
隐式绑定会自动解析 Eloquent 模型。
### 2. 自定义键名
```php
// 使用 username 而不是 id 来解析用户
Route::get('api/users/{user:username}', function (App\User $user) {
return $user;
});
```
### 3. 频率限制
```php
Route::middleware('throttle:60,1')->group(function () {
Route::get('/user', function () {
// 每分钟最多 60 次请求
});
});
```
### 4. 跨域资源共享 (CORS)
```php
Route::middleware('cors')->group(function () {
Route::get('/api/user', function () {
//
});
});
```
## 五、中间件的高级用法
### 1. 中间件组
```php
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
// ...
],
'api' => [
'throttle:60,1',
'bindings',
// ...
],
];
```
使用:
```php
Route::get('/', function () {
//
})->middleware('web');
Route::group(['middleware' => ['api']], function () {
Route::get('/api/user', function () {
// 使用 api 中间件组
});
});
```
### 2. 可终止中间件
```php
public function handle($request, Closure $next)
{
return $next($request);
}
public function terminate($request, $response)
{
// 在响应发送到浏览器后执行
}
```
### 3. 中间件优先级
在 `$middlewarePriority` 属性中定义中间件执行顺序:
```php
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\Authenticate::class,
// ...
];
```
## 六、最佳实践
1. **路由缓存**:在生产环境中使用路由缓存可以显著提高性能
```bash
php artisan route:cache
```
2. **合理组织路由**:将相关的路由分组,使用前缀和命名空间保持整洁
3. **中间件职责单一**:每个中间件应该只负责一项任务
4. **适当使用中间件组**:将常用的中间件组合在一起简化路由定义
5. **使用命名路由**:便于维护和生成 URL
通过掌握 Laravel 的路由和中间件系统,你可以构建出结构良好、安全且易于维护的 Web 应用程序。这两个组件是 Laravel 强大功能的基础,理解它们的工作原理将大大提高你的开发效率。