4 * @see https://github.com/laminas/laminas-httphandlerrunner for the canonical source repository
5 * @copyright https://github.com/laminas/laminas-httphandlerrunner/blob/master/COPYRIGHT.md
6 * @license https://github.com/laminas/laminas-httphandlerrunner/blob/master/LICENSE.md New BSD License
9 declare(strict_types=1);
11 namespace Laminas\HttpHandlerRunner;
13 use Psr\Http\Message\ResponseInterface;
14 use Psr\Http\Message\ServerRequestInterface;
15 use Psr\Http\Server\RequestHandlerInterface;
19 * "Run" a request handler.
21 * The RequestHandlerRunner will marshal a request using the composed factory, and
22 * then pass the request to the composed handler. Finally, it emits the response
23 * returned by the handler using the composed emitter.
25 * If the factory for generating the request raises an exception or throwable,
26 * then the runner will use the composed error response generator to generate a
27 * response, based on the exception or throwable raised.
29 class RequestHandlerRunner
32 * @var Emitter\EmitterInterface
37 * A request handler to run as the application.
39 * @var RequestHandlerInterface
44 * A factory capable of generating an error response in the scenario that
45 * the $serverRequestFactory raises an exception during generation of the
48 * The factory will receive the Throwable or Exception that caused the error,
49 * and must return a Psr\Http\Message\ResponseInterface instance.
53 private $serverRequestErrorResponseGenerator;
56 * A factory capable of generating a Psr\Http\Message\ServerRequestInterface instance.
57 * The factory will not receive any arguments.
61 private $serverRequestFactory;
63 public function __construct(
64 RequestHandlerInterface $handler,
65 Emitter\EmitterInterface $emitter,
66 callable $serverRequestFactory,
67 callable $serverRequestErrorResponseGenerator
69 $this->handler = $handler;
70 $this->emitter = $emitter;
72 // Factories are cast as Closures to ensure return type safety.
73 $this->serverRequestFactory = function () use ($serverRequestFactory) : ServerRequestInterface {
74 return $serverRequestFactory();
77 $this->serverRequestErrorResponseGenerator =
78 function (Throwable $exception) use ($serverRequestErrorResponseGenerator) : ResponseInterface {
79 return $serverRequestErrorResponseGenerator($exception);
86 public function run() : void
89 $request = ($this->serverRequestFactory)();
90 } catch (Throwable $e) {
91 // Error in generating the request
92 $this->emitMarshalServerRequestException($e);
96 $response = $this->handler->handle($request);
98 $this->emitter->emit($response);
101 private function emitMarshalServerRequestException(Throwable $exception) : void
103 $response = ($this->serverRequestErrorResponseGenerator)($exception);
104 $this->emitter->emit($response);