Yii Router
The package provides PSR-7 compatible request routing and a PSR-compatible middleware ready to be used in an application. Instead of implementing routing from groud up, the package provides an interface for configuring routes and could be used with one of the following adapter packages:
- FastRoute
- ...
General usage
use Yiisoft\Router\Group;
use Yiisoft\Router\Route;
use Yiisoft\Router\RouteCollection;
use Yiisoft\Router\RouteCollectorInterface;
use Yiisoft\Router\Fastroute\UrlMatcher;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
$routes = [
Route::get('/', static function (ServerRequestInterface $request, RequestHandlerInterface $next) use ($responseFactory) {
$response = $responseFactory->createResponse();
$response->getBody()->write('You are at homepage.');
return $response;
}),
Route::get('/test/{id:\w+}', static function (ServerRequestInterface $request, RequestHandlerInterface $next) use ($responseFactory) {
$id = $request->getAttribute('id');
$response = $responseFactory->createResponse();
$response->getBody()->write('You are at test with param ' . $id);
return $response;
})
];
$collector = $container->get(RouteCollectorInterface::class);
$collector->addGroup(Group::create(null, $routes));
$urlMatcher = new UrlMatcher(new RouteCollection($collector));
// $request is PSR-7 ServerRequestInterface
$result = $urlMatcher->match($request);
if (!$result->isSuccess()) {
// 404
}
// $result->parameters() contains parameters from the match
// run middleware assigned to a route found
$response = $result->process($request, $handler);
UrlGeneratorInterface
and UrlMatcher
are specific to adapter package used. See its readme on how to properly
configure it.
In middleware()
and prependMiddleware()
you can either specify PSR middleware class name or a callback.
Note that pattern specified for routes depends on the underlying routing library used.
Route groups
Routes could be grouped. That is useful for API endpoints and similar cases:
use \Yiisoft\Router\Route;
use \Yiisoft\Router\Group;
use \Yiisoft\Router\RouteCollectorInterface;
// for obtaining router see adapter package of choice readme
$collector = $container->get(RouteCollectorInterface::class);
$collector->addGroup(Group::create('/api', [
Route::get('/comments'),
Group::create('/posts', [
Route::get('/list'),
]),
]));
Middleware usage
In order to simplify usage in PSR-middleware based application, there is a ready to use middleware provided:
$router = $container->get(Yiisoft\Router\UrlMatcherInterface::class);
$responseFactory = $container->get(\Psr\Http\Message\ResponseFactoryInterface::class);
$routerMiddleware = new Yiisoft\Router\Middleware\Router($router, $responseFactory, $container);
// add middleware to your middleware handler of choice
In case of a route match router middleware executes handler middleware attached to the route. If there is no match, next application middleware processes the request.
Creating URLs
URLs could be created using UrlGeneratorInterface::generate()
. Let's assume a route is defined like the following:
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Yiisoft\Yii\Web\SapiEmitter;
use Yiisoft\Yii\Web\ServerRequestFactory;
use Yiisoft\Yii\Web\NotFoundHandler;
use Yiisoft\Router\Route;
use Yiisoft\Router\RouteCollection;
use Yiisoft\Router\RouteCollectorInterface;
use Yiisoft\Router\Fastroute\UrlMatcher;
$request = $container->get(ServerRequestFactory::class)->createFromGlobals();
$responseFactory = $container->get(ResponseFactoryInterface::class);
$notFoundHandler = new NotFoundHandler($responseFactory);
$collector = $container->get(RouteCollectorInterface::class);
$collector->addRoute(Route::get('/test/{id:\w+}', static function (ServerRequestInterface $request, RequestHandlerInterface $next) use ($responseFactory) {
$id = $request->getAttribute('id');
$response = $responseFactory->createResponse();
$response->getBody()->write('You are at test with param ' . $id);
return $response;
})->name('test'));
$router = new UrlMatcher(new RouteCollection($collector));
$route = $router->match($request);
$response = $route->process($request, $notFoundHandler);
$emitter = new SapiEmitter();
$emitter->emit($response, $request->getMethod() === Method::HEAD);
Then that is how URL could be obtained for it:
use Yiisoft\Router\UrlGeneratorInterface;
function getUrl(UrlGeneratorInterface $urlGenerator, $parameters = [])
{
return $urlGenerator->generate('test', $parameters);
}
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. To run it:
./vendor/bin/infection
Static analysis
The code is statically analyzed with Psalm. To run static analysis:
./vendor/bin/psalm
Support the project
Follow updates
License
The Yii Router is free software. It is released under the terms of the BSD License.
Please see LICENSE
for more information.
Maintained by Yii Software.