简单实现webman类似tp在控制器中定义中间件

kyour

webman不支持在控制器中定义中间件,因为迁移tp代码自己实现了控制器中间件支持,分享同时也请大家指点指点。
贴代码:
首先创建自己的控制器中间件接口

<?php

namespace app\common\middleware;

use Webman\Http\Request;
use Webman\Http\Response;

interface ControllerMiddlewareInterface
{

    /**
     * 控制器专用中间件接口
     */
    public function process(Request $request): ?Response;

}

创建webman中间件以调用自己的控制器中间件

<?php

namespace app\common\middleware;

use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;

class ControllerMiddleware implements MiddlewareInterface
{

    /**
     * 实现控制器中间件处理
     * @param Request $request
     * @param callable $handler
     * @return Response
     */
    public function process(Request $request, callable $handler) : Response
    {
        $controllerClass = $request->controller;

        try{
            $middlewareConfig = $controllerClass::middleware;
        }catch (\Throwable $e){
            //没有定义控制器中间件
            $middlewareConfig = [];
        }
        if($middlewareConfig){
            //如果存在中间件,则调用控制器中间件
            foreach ($middlewareConfig as $middlewareClass) {
                /**
                 * @var ControllerMiddlewareInterface $middleware
                 */
                $middleware = new $middlewareClass();

                //调用中间件,若有响应则中断请求
                if($res = $middleware->process($request)){
                    return $res;
                }
            }
        }

        return $handler($request);
    }
}

实现一个控制器中间件,demo如下

<?php

namespace app\common\middleware;

use Webman\Http\Request;
use Webman\Http\Response;

/**
 * 鉴权中间件
 */
class AuthMiddleware implements ControllerMiddlewareInterface
{

    /**
     * @param Request $request
     * @return Response
     */
    public function process(Request $request) : ?Response
    {
        if($request->isAjax()){
            return new Response(200, [], '不允许ajax提交');
        }

        return null;
    }
}

将实现的控制器中间件添加到控制器中

<?php
namespace plugin\admin\app\controller;

use app\BaseController;

class Index extends BaseController
{
    /**
     * 控制器中间件
     */
    const middleware = [
        \app\common\middleware\AuthMiddleware::class
    ];

    public function index()
    {
        return "hello admin.";
    }
}

最后,将webman中间件添加到配置中(middleware.php)

<?php
use App\common\middleware\ControllerMiddleware;

return [
    '' => [
        //...你的其他中间件配置

        //控制器中间件
        ControllerMiddleware::class

    ]
];
1011 2 0
2个评论

admin
  • Tinywan 2023-02-02

    哈哈

  • kyour 2023-03-03

    在控制器里能定义使用什么中间件吗?我没有看到

hxg2050

差个$handler,我帮你补充下

<?php

namespace app\common\middleware;

use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;

class ControllerMiddleware implements MiddlewareInterface
{

    /**
     * 实现控制器中间件处理
     * @param Request $request
     * @param callable $handler
     * @return Response
     */
    public function process(Request $request, callable $handler): Response
    {
        $controllerClass = $request->controller;

        try {
            $middlewareConfig = $controllerClass::middleware;
        } catch (\Throwable $e) {
            //没有定义控制器中间件
            $middlewareConfig = [];
        }
        if ($middlewareConfig) {
            //如果存在中间件,则调用控制器中间件
            $count = count($middlewareConfig);
            $index = 0;
            $call = function (Request $request) use (&$call, $middlewareConfig, $handler, $count, &$index) {
                $middlewareClass = $middlewareConfig[$index];
                $index ++;
                $middleware = new $middlewareClass();
                return $middleware->process($request, $index == $count ? $handler : $call);
            };
            return $call($request);
        }

        return $handler($request);
    }
}
  • 暂无评论

kyour

260
积分
0
获赞数
0
粉丝数
2022-12-31 加入
🔝