在THINKPHP中,排除某些操作跳过中间件的一些思路

文章讲述了在Thinkphp框架中,如何在多应用环境下,针对特定应用和控制器操作,如api/login/other,实现跳过中间件的检查。介绍了使用控制器、应用和路由中间件的不同方法,以及如何在全局或应用级别设置中间件并排除特定操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:希望在多应用下,在指定的某个应用中,使用了中间件做类似登录检测的时候,应用下的某些操作,可以跳过这个中间件。

例如:api 应用的 login 这个控制器下下面有几个操作,例如 info,login,logout、other

对应的路径分别是 api/login/info、api/login/login、api/login/logout、api/login/other、但是我们想对 api/login/other 这个操作跳过中间件检查。

Thinkphp中,可以用的中间件有 全局中间件、应用中间件、路由中间件、控制器中间件

其实控制器中间件,大概可以支持这个需求,看官方文档:

如果需要设置控制器中间的生效操作,可以如下定义:

<?php
namespace app\controller;


class Index
{
    protected $middleware = [ 
    	'auth' 	=> ['except' 	=> ['hello'] ],//---这里是排除的操作执行中间件
        'check' => ['only' 		=> ['hello'] ],//---这里是仅仅某个操作执行中间件
    ];

    public function index()
    {
        return 'index';
    }

    public function hello()
    {
        return 'hello';
    }
}

由于项目需要在中间件中根据输入的值进行简单处理或,把用户id作为传递值提交给控制器,然后在控制器中 在 __construct 获取由中间件的传递的值,并进行初始化操作。

但在使用过程中发现,如果使用控制中间件,无法在中间件传值,原因参考这里:CSDNicon-default.png?t=N7T8https://mp.csdn.net/mp_blog/creation/editor/134923605

转而使用  应用中间件,但是在应用控制中,传值是可以传值了,但是我需要在应用的某个操作中,要跳过控制器,所以需要在控制器中获取到 当前控制器和当前操作

#当前控制器
    $controller = $request->controller();
    #当前操作
    $action = $request->action();

但在应用控制器中,无法获得当前控制器的值、当前操作值,总之上面两个是没办法获取到值的。

原本想尝试用路由中间件,可是无论如何定义路由,在多应用中,如果我只是想排除某个操作跳过中间件检测,操作起来还是比较麻烦的

最后测试了一下,发现路由中间件可以满足。

在THINKPHP的官方文档中提到:

如果你希望某个路由中间件是全局执行(不管路由是否匹配),可以不需要在路由里面定义,支持直接在路由配置文件中定义,例如在config/route.php配置文件中添加:

'middleware'    =>    [
    app\middleware\Auth::class,
    app\middleware\Check::class,
],

这样,所有该应用下的请求都会执行AuthCheck中间件。

我们可以把这个全局路由中间件,作为某个应用下的全局中间件,只在作用在某个应用下。具体操作如下:

第一步:在某个应用下,例如api下新建一个 config文件夹,然后新建 route.php文件

route.php文件内容大致是这样:

<?php
return [
  //路由中间件
  'middleware' => [
    \app\api\middleware\Check::class, // 检测状态
  ],
];

这样,这个应用下,都会运行这个中间件。接下来我们要排除掉某些操作

在这个应用的某个控制器下,定义一个公共变量 skipMiddleware  ,代码片段大致如下

<?php
declare (strict_types = 1);

namespace app\api\controller;

use think\Request;

class Index
{
  //跳过中间件检测的action,
  public $skipMiddleware = ['index']; //--》这里定义了一个跳过中间件的数组,数组的成员名称,就是你要跳过的操作名称
  //public $onlyMiddleware = ['index'];

//balabababa 
//balabababa 主代码部分省略
//balabababa 

}

然后我们在中间件中处理一下逻辑,代码大致如下

<?php
#中间件
namespace app\api\middleware;

class Check
{
  public function handle($request, \Closure $next)
  {
    #获取当前应用
    $appname = app('http')->getName();
    #当前控制器
    $controller = $request->controller();
    #当前操作
    $action = $request->action();
    
    #自动定位到控制器,取出设置的变量
    $class = "\app\\{$appname}\controller\\{$controller}";
    $model = new $class($request);
    
    #跳过中间件的设置
    if(
        property_exists($model, 'skipMiddleware') 
        && 
        $model->skipMiddleware 
        && 
       in_array($action,$model->skipMiddleware)
     ){
      return $next($request);
    };
    
//没跳过部分的代码略

上面是实现了指定某些操作下,跳过中间件检查。

ThinkPHP8中创建和使用路由中间件的步骤可以分为以下几个部分: 1. 创建中间件: 首先,你需要在应用的中间件目录中创建一个新的中间件类。通常这个目录是 `application\index\middleware`,但具体的路径可能因应用的命名空间而有所不同。你可以通过ThinkPHP提供的命令行工具来创建一个新的中间件: ``` php think make:middleware CheckAuth ``` 执行上述命令后,会在指定目录生成一个名为 `CheckAuth` 的中间件类文件。 2. 定义中间件逻辑: 在生成的中间件类文件中,你需要实现 `handle` 方法,这个方法会在请求到达控制器之前被调用。在这个方法中,你可以定义需要的逻辑,例如权限检查、请求日志记录等: ```php namespace app\index\middleware; use Closure; class CheckAuth { public function handle($request, Closure $next) { // 在这里添加中间件逻辑,例如检查用户是否已登录 if (/* 检查条件 */) { // 如果用户未通过检查,可以重定向到其他页面或返回错误信息 return redirect('login'); } // 如果通过检查,则继续请求处理流程 return $next($request); } } ``` 3. 注册中间件: 创建并实现中间件逻辑之后,你需要在应用的路由配置文件中注册这个中间件。通常是 `route` 目录下的 `route.php` 文件。你可以在该文件中使用中间件: ```php use app\index\middleware\CheckAuth; // 注册全局中间件 $middleware = \app\http\middleware\CheckAuth::class; $route->middleware($middleware); // 或者为特定路由注册中间件 $route->get('admin', 'admin/Index/index')->middleware($middleware); ``` 通过这些步骤,你就可以在ThinkPHP8中创建和使用路由中间件了。记得根据你的实际应用结构和需求调整上述代码示例中的路径和类名。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值