【问题标题】:How to call function (controller action) in PSR-15 middleware stack如何在 PSR-15 中间件堆栈中调用函数(控制器操作)
【发布时间】:2019-08-24 23:35:23
【问题描述】:

我已经阅读了来自PHP-FIG(HTTP 服务器请求处理程序)的 PSR-15,并且想知道何时调用了一个动作(控制器动作或闭包)。

通过所有中间件进行处理时,应在通过所有中间件后调用该操作。在操作之后,所有中间件再次从内部传递到外部(如 Slim 框架的User Guide 中所述)。

我在 GitHub 上浏览了 Laravel 中的代码,但不知道他们是如何调用动作然后再次遍历所有中间件的。

answer 告诉我 Slim 将自己添加到中间件堆栈中。我猜它然后以某种方式执行动作。但是,Slim 使用的是双通道。

中间件堆栈和执行如何通过单次传递(如 PSR-15 中所述)并在所有中间件之间调用操作?

【问题讨论】:

  • 我在同一条船上。我们目前有一个设置,我们有一个路由器文件,它计算出要调用的控制器,然后调用控制器。在控制器的构造中,我们执行了许多不同的任务,例如 OAuth 验证、速率限制检查等。我想将所有这些额外的功能分解到中间件中。我一直在试图弄清楚从哪里调用这些中间件,从哪里绑定请求处理程序,以及在这种情况下它到底需要做什么。

标签: php controller action middleware php-fig


【解决方案1】:

我开始实际添加控制器作为中间件。为此,RequestHandler 必须能够接受要添加的新中间件。我的路由器负责分配适当的中间件。这样我还可以为每条路线分配多个操作。

【讨论】:

    【解决方案2】:

    这是一个示例代码,我可以想象它可以工作。当然,还缺少很多东西,比如设置路由、解决依赖关系、PSR 接口和其他框架附带的东西。

    此代码将中间件和操作添加到请求处理程序,请求处理程序可以在需要时执行。

    <?php
    
    interface RequestInterface {}
    class Request implements RequestInterface {}
    
    interface ResponseInterface {}
    class Response implements ResponseInterface {}
    class Response404 implements ResponseInterface {}
    
    class FirstMiddleware {
    
        public function process(RequestInterface $request, RequestHandler $handler): ResponseInterface {
            echo ' First-Before ';
    
            $response = $handler->handle($request);
    
            echo ' First-After ';
    
            return $response;
        }
    
    }
    
    class SecondMiddleware {
    
        public function process(Request $request, RequestHandler $handler): Response {
            echo ' Second-Before ';
    
            $response = $handler->handle($request);
    
            echo ' Second-After ';
    
            return $response;
        }
    
    }
    
    class RequestHandler {
    
        private $middleware;
        private $callable;
        private $params;
    
        public function __construct(array $middleware = [], callable $callable, array $params = []) {
            $this->middleware = $middleware;
            $this->callable = $callable;
            $this->params = $params;
        }
    
        public function handle(RequestInterface $request): ResponseInterface {
            $middleware = current($this->middleware);
            next($this->middleware);
    
            if (!$middleware) {
                $response = ($this->callable)(...$this->params);
    
                return $response;
            }
    
            return $middleware->process($request, $this);
        }
    
    }
    
    class App {
    
        private $middleware = [];
        private $callable;
    
        public function setMiddleware(array $middleware) {
            $this->middleware = $middleware;
        }
    
        public function setCallable(callable $callable) {
            $this->callable = $callable;
        }
    
        public function run() {
            $handler = new RequestHandler($this->middleware, $this->callable, ['one', 'two']);
            $handler->handle(new Request());
        }
    
    }
    
    class Controller {
    
        public function action($a, $b) {
            echo ' Controller Action ';
            echo $a;
            echo $b;
    
            return new Response();
        }
    
    }
    
    $middleware = [
        new FirstMiddleware(),
        new SecondMiddleware(),
    ];
    
    // Using closure ...
    $callable = function ($a, $b) {
        echo ' Closure Action ';
        echo $a;
        echo $b;
    
        return new Response();
    };
    
    // Or an object method
    $controller = new Controller();
    $callable = array($controller, 'action');
    
    /** Run */
    
    $app = new App();
    
    $app->setMiddleware($middleware);
    $app->setCallable($callable);
    
    $app->run();
    

    【讨论】:

      猜你喜欢
      • 2019-03-27
      • 1970-01-01
      • 2015-04-08
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      • 1970-01-01
      • 1970-01-01
      • 2015-08-24
      相关资源
      最近更新 更多