PHP项目框架中间件如何开发使用

wen PHP项目 18

本文目录导读:

PHP项目框架中间件如何开发使用

  1. 核心概念
  2. Laravel 中间件实战 (最常用)
  3. ThinkPHP 6+ 中间件实战
  4. 高级技巧与多参数中间件
  5. 最佳实践建议

在 PHP 项目框架中,中间件(Middleware)是一种非常强大的机制,用于在请求到达控制器之前响应返回给客户端之前执行特定的逻辑。

下面我将以当前最主流的 PHP 框架 LaravelThinkPHP 为例,详细讲解中间件的开发和使用方法,这两个框架的中间件概念类似,但实现细节不同。


核心概念

中间件就像一个“过滤层”或“处理管道”,请求必须通过这些管道才能到达最终的处理程序(控制器)。

常见用途:

  • 身份认证(Auth)
  • 日志记录
  • 跨域请求(CORS)
  • CSRF 保护
  • 请求频率限制
  • 请求数据过滤

Laravel 中间件实战 (最常用)

Laravel 的中间件是所有 PHP 框架中最成熟的实现之一。

创建中间件

使用 Artisan 命令创建:

php artisan make:middleware CheckAge

这会在 app/Http/Middleware/CheckAge.php 生成文件。

编写中间件逻辑

核心逻辑写在 handle 方法中。

示例:年龄验证中间件

<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class CheckAge
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        // 1. 前置逻辑:请求到达控制器之前执行的代码
        if ($request->age < 18) {
            // 如果年龄小于18,直接返回响应,终止请求继续往下走
            return redirect('home'); 
        }
        // 2. 传递请求到下一个中间件或控制器
        $response = $next($request);
        // 3. 后置逻辑:控制器处理完后的响应处理
        // 给响应头部添加自定义信息
        $response->headers->set('X-Middleware-Info', 'Age checked');
        return $response;
    }
}

关键点解析:

  • $next($request):将请求传递给管道中的下一个处理器,如果不调用,请求链就会终止。
  • $next 之前的代码是前置中间件(请求来时执行)。
  • $next 之后的代码是后置中间件(响应返回时执行)。

注册中间件

需要告诉 Laravel 这个中间件存在,打开 app/Http/Kernel.php

有三种注册方式:

  • 全局中间件:所有 HTTP 请求都会经过。

    // 在 $middleware 属性中添加
    protected $middleware = [
        // \App\Http\Middleware\TrustProxies::class,
        \App\Http\Middleware\CheckAge::class, // 添加这行
    ];
  • 路由中间件:只有在特定路由或路由组中使用时才会执行(推荐,更灵活)。

    // 在 $routeMiddleware 属性中添加
    protected $routeMiddleware = [
        // 'auth' => \App\Http\Middleware\Authenticate::class,
        'check.age' => \App\Http\Middleware\CheckAge::class, // 给中间件起个名字 'check.age'
    ];

使用中间件

routes/web.phproutes/api.php 中应用。

use Illuminate\Support\Facades\Route;
// 方式一:单个路由使用
Route::get('/admin/profile', function () {
    // ...
})->middleware('check.age');
// 方式二:路由组使用(最常见)
Route::middleware(['check.age'])->group(function () {
    Route::get('/admin/dashboard', [AdminController::class, 'dashboard']);
    Route::get('/admin/settings', [AdminController::class, 'settings']);
});

ThinkPHP 6+ 中间件实战

ThinkPHP 6 引入了与 Laravel 非常相似的中间件机制。

创建中间件

使用命令创建(需要安装 topthink/think-middleware)或手动创建:

php think make:middleware CheckAge

文件生成在 app/middleware/CheckAge.php

编写中间件逻辑

ThinkPHP 的核心方法是 handle,签名略有不同。

<?php
declare (strict_types=1);
namespace app\middleware;
use Closure;
class CheckAge
{
    /**
     * 处理请求
     *
     * @param \think\Request $request
     * @param \Closure       $next
     * @return Response
     */
    public function handle($request, \Closure $next)
    {
        // 前置逻辑
        if ($request->param('age') < 18) {
            // 终止请求,返回错误
            return redirect('/home');
        }
        // 传递请求
        $response = $next($request);
        // 后置逻辑
        $response->header('X-Middleware-Info', 'Age checked');
        return $response;
    }
}

注册中间件

打开 app/middleware.php 配置文件(如果没有则创建)。

// 全局注册
return [
    // 全局中间件
    app\middleware\CheckAge::class,
    // 或者为特定模块注册
];

分组注册(推荐):app/provider.phproute/app.php 中。

// 在 route.php 中
use think\facade\Route;
Route::group('admin', function () {
    Route::rule('dashboard', 'admin/index/dashboard');
    Route::rule('settings', 'admin/index/settings');
})->middleware(\app\middleware\CheckAge::class);

使用

ThinkPHP 6 支持在控制器构造函数中定义中间件。

// 在控制器中
protected $middleware = [
    \app\middleware\CheckAge::class => ['except' => ['login', 'register']],
];

高级技巧与多参数中间件

带参数的中间件 (Laravel 示例)

如果你想让中间件更灵活,比如要求年龄大于某个值。

// app/Http/Middleware/CheckAge.php
public function handle(Request $request, Closure $next, $minAge)
{
    if ($request->age < $minAge) {
        return redirect('home');
    }
    return $next($request);
}

使用:

Route::get('/admin/profile', function () {
    // ...
})->middleware('check.age:18'); // 冒号后传参

终止中间件 (Terminable Middleware)

有时需要在 HTTP 响应发送之后执行一些操作(例如记录日志或缓存),Laravel 支持 terminate 方法。

public function terminate($request, $response)
{
    // 响应已发送,执行后处理
    Log::info('Request processed');
}

中间件的执行顺序

  • 全局中间件 最先执行。
  • 路由中间件 按注册顺序执行。
  • 在同一个路由组中,中间件的顺序很重要,前面的先执行(前置)或后执行(后置)。

最佳实践建议

  1. 保持单一职责:一个中间件只做一件事(如:CheckAge 只检查年龄,Auth 只做认证)。
  2. 优先使用路由中间件:全局中间件会使所有请求都变慢,只在你需要的地方使用中间件。
  3. 注意性能:不要在中间件中执行耗时的数据库查询或文件 IO。
  4. 异常处理:如果中间件检测到问题,直接返回 response() 或抛出 HttpException 而不要继续处理。
  5. 测试中间件:中间件是逻辑集中的地方,务必编写单元测试。

无论是 Laravel 还是 ThinkPHP,中间件的核心思想都是“请求处理管道”

  • 创建 -> 编写 handle 方法。
  • 注册 -> 在 Kernel 或配置文件中注册。
  • 使用 -> 在路由或控制器中指定。

掌握了中间件,你就掌握了现代 PHP 框架的核心设计模式之一,能够极大地提高代码的复用性和可维护性。

抱歉,评论功能暂时关闭!