How to call middleware PSR-15 within event listeners in zend framework 3 (zend-mvc)?

Hi, guys!
Here https://docs.zendframework.com/zend-mvc/cookbook/middleware-in-listeners/ are docs about how to use middleware PSR-7 within event listeners. There is example of middleware with __invoke() method of middleware.

How to call middleware PSR-15 with process() method of middleware class within event listeners?

Upd:

Here https://docs.zendframework.com/zend-mvc/middleware/#writing-middleware is example of how to write middleware with process() method of middleware class, but there is nothing about how to call it in event listener. Besides, __https://github.com/http-interop/http-middleware from docs is now deprecated. Can somebody give me some modern example of using middleware PSR-15 with process() method of middleware class within event listeners?

Upd2:

zend-httphandlerrunner - Is this what I need for PSR-15 middleware within event listener? How to use that?

Upd3:

zend-stratigility __https://docs.zendframework.com/zend-stratigility/v3/middleware/#psr-15-middleware support PSR-15 middleware but how to use it within event listeners in zend framework 3 (zend-mvc)?

It’s almost exactly the same. The only differences are:

  • $done needs to be a PSR-15 request handler.
  • You call the process() method of the middleware.

So, taking the Module example from that original page:

namespace Application;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zend\Psr7Bridge\Psr7Response;
use Zend\Psr7Bridge\Psr7ServerRequest;

class Module
{
    public function onBootstrap($e)
    {
        $app          = $e->getApplication();
        $eventManager = $app->getEventManager();
        $services     = $app->getServiceManager();

        $eventManager->attach($e::EVENT_DISPATCH, function ($e) use ($services) {
            $request  = Psr7ServerRequest::fromZend($e->getRequest());
            $response = Psr7Response::fromZend($e->getResponse());
            $done     = new class($response) implements RequestHandlerInterface {
                private $response;

                public function __construct(ResponseInterface $response)
                {
                    $this->response = $response;
                }

                public function handle(ServerRequestInterface $request) : ResponseInterface
                {
                    return $this->response;
                }
            };

            $result = $services->get(Middleware\AuthorizationMiddleware::class)
                ->process(
                    $request,
                    $done
                );

            if ($result !== $response) {
                return Psr7Response::toZend($result);
            }
        }, 2);
    }
}

In this example, I created an anonymous class as the handler, and have it return a response based off the current zend-http response. If the middleware returns that verbatim, without changes, we can assume that the middleware did not do anything to the response, and thus can continue processing the request with other listeners. Otherwise, we return the response from the middleware, after first converting it to zend-http, and short-circuit execution.

1 Like

I didn’t find RequestHandlerInterface inside zend frameworks’ components that is why I have used RequestHandlerInterface implementation from “Relay\Relay” library. And my code inside “$eventManager->attach($e::EVENT_DISPATCH …” looks like:

    $request  = Psr7ServerRequest::fromZend($e->getRequest());
    
    $queue = [];
    
    $queue[] = $services->get(Middleware\AuthorizationMiddleware::class); 
    
    $relay = new Relay($queue);
    
    $relay->handle($request);

It seems it works for me but I am not 100% sure. Should I rewrite my current code?

RequestHandlerInterface is part of PSR-15. We provide a few implementations, but for the most part, it is something your application will provide. The example I had above provides an anonymous class declaration of it, for purposes of determining whether or not the middleware returned a different response.

Relay definitely works. So does Zend\Stratigility\MiddlewarePipe. :wink:

1 Like