Laravel 是当前最流行的 PHP 框架之一,它的路由与中间件机制是理解整个请求生命周期的钥匙。从请求进入应用、经过中间件过滤、匹配路由、分发到控制器、最终返回响应,这条链路清晰而优雅。本文带你走完这条链路的每一环。
一、路由定义:请求的入口
Laravel 路由定义在 routes/web.php(web 路由)和 routes/api.php(API 路由)。每条路由声明了 HTTP 方法、URI 与处理逻辑。
// routes/web.php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
// 基础闭包路由
Route::get('/', function () {
return view('welcome');
});
// RESTful 资源路由:一次生成 index/create/store/show/edit/update/destroy
Route::resource('posts', PostController::class);
// 路由分组:共享前缀、中间件、命名空间
Route::prefix('admin')->middleware(['auth', 'admin'])->group(function () {
Route::get('/dashboard', [AdminController::class, 'dashboard'])->name('admin.dashboard');
Route::resource('users', UserController::class);
});
路由命名(->name())让你在代码里用 route('admin.dashboard') 生成 URL,URI 变了也不用改引用处。
二、中间件:请求的过滤层
中间件是请求进入控制器前、响应返回浏览器前的"过滤层"。典型用途包括认证、CORS、日志、限流。它形成一条管道,每个中间件都可以在请求前、响应后做处理。
// 生成中间件:php artisan make:middleware CheckAge
// app/Http/Middleware/CheckAge.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class CheckAge
{
public function handle(Request $request, Closure $next)
{
// 请求前置逻辑
if ($request->age < 18) {
return response('未成年禁止访问', 403);
}
$response = $next($request); // 传递给下一层
// 响应后置逻辑
return $response;
}
}
心智模型:中间件像洋葱,请求从外向内穿过每一层,响应再从内向外穿出。$next($request) 是"放行"的关键。
注册中间件到 app/Http/Kernel.php,可全局生效,也可作为路由中间件按需挂载:
// 仅给某条路由挂中间件
Route::get('/profile', [UserController::class, 'profile'])
->middleware('auth', 'check.age');
三、控制器:业务逻辑的归处
路由闭包适合简单逻辑,复杂业务应放到控制器。Laravel 的控制器支持依赖注入,类型提示的参数会被容器自动解析。
namespace App\Http\Controllers;
use App\Http\Requests\StorePostRequest;
use App\Models\Post;
use App\Services\SlugService;
use Illuminate\Http\Request;
class PostController extends Controller
{
// 构造函数注入:服务由容器解析
public function __construct(protected SlugService $slug) {}
public function store(StorePostRequest $request)
{
// Request 注入:表单验证已在 StorePostRequest::rules() 完成
$data = $request->validated();
$data['slug'] = $this->slug->generate($data['title']);
$post = Post::create($data);
return response()->json($post, 201);
}
}
四、依赖注入与服务容器
Laravel 的服务容器是依赖注入的核心。绑定接口到实现,解析时自动注入依赖,让代码解耦、易测试。
// 绑定接口到实现
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->bind(
\App\Contracts\PaymentInterface::class,
\App\Services\AlipayService::class
);
}
// 使用时类型提示即可,容器自动解析
class OrderController
{
public function pay(\App\Contracts\PaymentInterface $payment)
{
$payment->charge(100);
}
}
bind 每次解析都返回新实例,singleton 全局共享一个实例。单例适合无状态的连接池、配置类。
五、请求生命周期串讲
把上面几个概念串起来,一个完整请求的流程是:
- 入口:请求进入
public/index.php,启动应用。 - 路由匹配:Router 根据 URI+方法找到匹配路由。
- 中间件管道:依次执行全局中间件、路由中间件。
- 控制器执行:依赖注入解析参数,调用控制器方法。
- 响应返回:响应反向穿过中间件管道,返回浏览器。
// 简化的中间件管道示意
$pipeline = array_reduce($middlewares, function ($next, $middleware) {
return function ($request) use ($middleware, $next) {
return $middleware->handle($request, $next);
};
}, $finalHandler);
return $pipeline($request);
六、实战建议
- 路由分组:按业务模块分组,统一前缀与中间件,避免重复。
- 中间件职责单一:一个中间件只做一件事(认证、限流、日志分开),便于复用与测试。
- 用 FormRequest 做校验:把验证规则抽到 Request 类,控制器保持干净。
- 面向接口编程:依赖接口而非具体类,配合容器绑定,便于替换实现与单元测试。
Laravel 的优雅来自于它对"请求生命周期"的清晰抽象。理解了路由、中间件、控制器、容器这四块如何协作,你就掌握了 Laravel 工程化的骨架,剩下的视图、ORM、队列都是在这套骨架上的能力扩展。