yiisoft / middleware-dispatcher
PSR-15 middleware dispatcher
Fund package maintenance!
Open Collective
yiisoft
Installs: 196 498
Dependents: 15
Suggesters: 0
Security: 0
Stars: 13
Watchers: 15
Forks: 7
Open Issues: 0
Requires
- php: ^8.0
- psr/container: ^1.0|^2.0
- psr/event-dispatcher: ^1.0
- psr/http-message: ^1.0|^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- yiisoft/definitions: ^2.0|^3.0
- yiisoft/friendly-exception: ^1.1
- yiisoft/injector: ^1.0
Requires (Dev)
- maglnet/composer-require-checker: ^4.2
- nyholm/psr7: ^1.4
- phpunit/phpunit: ^9.5
- rector/rector: ^0.18.0
- roave/infection-static-analysis-plugin: ^1.18
- spatie/phpunit-watcher: ^1.23
- vimeo/psalm: ^4.30|^5.3
- yiisoft/test-support: ^1.3
README
Yii Middleware Dispatcher
The package is a PSR-15 middleware dispatcher. Given a set of middleware and a request instance, dispatcher executes it produces a response instance.
Requirements
- PHP 8.0 or higher.
Installation
The package could be installed with composer:
composer require yiisoft/middleware-dispatcher
General usage
To use a dispatcher, you need to create it first:
use Yiisoft\Middleware\Dispatcher\MiddlewareDispatcher; use Yiisoft\Middleware\Dispatcher\MiddlewareFactory; $dispatcher = new MiddlewareDispatcher( new MiddlewareFactory($diContainer), $eventDispatcher );
In the above $diContainer
is an instance of PSR-11 \Psr\Container\ContainerInterface
and $eventDispatcher
is an instance of PSR-14 Psr\EventDispatcher\EventDispatcherInterface
.
After dispatcher instance obtained, it should be fed with some middleware:
$dispatcher = $dispatcher->withMiddlewares([ TeapotAccessChecker::class, static function (): ResponseInterface { return new Response(418); }, ]);
In the above we have used a callback. Overall the following options are available:
- A controller handler action in format
[TestController::class, 'index']
.TestController
instance will be created andindex()
method will be executed. - A name of PSR-15 middleware class. The middleware instance will be obtained from container.
- A name of PSR-15 request handler class. The request handler instance will be obtained from container and executed.
- A name or instance of invokable class. If the name of invokable class is provided, the instance will be obtained from container and executed.
- A function returning a middleware such as
static function (): MiddlewareInterface { return new TestMiddleware(); }
The middleware returned will be executed. - A callback
function(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
. - An array definition (see syntax) of middleware:
[ 'class' => MyMiddleware::class, '__construct()' => [ 'someVar' => 42, ], ]
For handler action and callable typed parameters are automatically injected using dependency injection container.
Current request and handler could be obtained by type-hinting for ServerRequestInterface
and RequestHandlerInterface
.
After middleware set is defined, you can do the dispatching:
$request = new ServerRequest('GET', '/teapot'); $response = $dispatcher->dispatch($request, $this->getRequestHandler());
Given a request dispatcher executes middleware in the set and produces response. First specified middleware will be
executed first. For each middleware
\Yiisoft\Middleware\Dispatcher\Event\BeforeMiddleware
and \Yiisoft\Middleware\Dispatcher\Event\AfterMiddleware
events are triggered.
Creating your own implementation of parameters resolver
Parameters resolver could be customized by providing your own ParametersResolverInterface
implementation:
use \Psr\Http\Message\ServerRequestInterface; use \Yiisoft\Middleware\Dispatcher\ParametersResolverInterface; class CoolParametersResolver implements ParametersResolverInterface { public function resolve(array $parameters, ServerRequestInterface $request): MiddlewareInterface { $resolvedParameters = []; foreach ($parameters as $name => $parameter) { if ($request->getAttribute($name) !== null) { $resolvedParameters[$name] = $request->getAttribute($name) } } return $resolvedParameters; } }
Then it could be used like the following:
use Yiisoft\Middleware\Dispatcher\MiddlewareDispatcher; use Yiisoft\Middleware\Dispatcher\MiddlewareFactory; $dispatcher = new MiddlewareDispatcher( new MiddlewareFactory($diContainer, new CoolParametersResolver()), $eventDispatcher );
To combine several parameters' resolvers use CompositeParametersResolver
:
use Yiisoft\Middleware\Dispatcher\CompositeParametersResolver; use Yiisoft\Middleware\Dispatcher\MiddlewareDispatcher; use Yiisoft\Middleware\Dispatcher\MiddlewareFactory; $dispatcher = new MiddlewareDispatcher( new MiddlewareFactory( $diContainer, new CompositeParametersResolver( new CoolParametersResolver(), new YetAnotherParametersResolver(), ) ), $eventDispatcher );
Testing
Unit testing
The package is tested with PHPUnit. To run tests:
./vendor/bin/phpunit
Mutation testing
The package tests are checked with Infection mutation framework with Infection Static Analysis Plugin. To run it:
./vendor/bin/roave-infection-static-analysis-plugin
Static analysis
The code is statically analyzed with Psalm. To run static analysis:
./vendor/bin/psalm
License
The Yii Middleware Dispatcher is free software. It is released under the terms of the BSD License.
Please see LICENSE
for more information.
Maintained by Yii Software.