fas / routing
Fast and simple router
0.7.2
2021-07-13 21:35 UTC
Requires
- php: >=7.4.0
- fas/autowire: ^0.2
- fas/exportable: ^0.2
- nikic/fast-route: ^1.3
- psr/http-message: ^1.0
- psr/http-server-middleware: ^1.0
Requires (Dev)
- filp/whoops: ^2.13
- laminas/laminas-diactoros: ^2.6
- laminas/laminas-httphandlerrunner: ^1.4
- nyholm/psr7: ^1.4
- phpmd/phpmd: ^2.10
- phpunit/phpunit: ^9
- squizlabs/php_codesniffer: ^3.6
Suggests
- filp/whoops: ^2.13
Provides
README
Installation
composer require fas/routing
Usage
An api on top of fastroute. With autowiring capabilities using a container or not.
Without container setup
<?php require __DIR__ . '/../vendor/autoload.php'; use Fas\Routing\Router; use Laminas\Diactoros\ResponseFactory; use Laminas\Diactoros\ServerRequestFactory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; $router = new Router; $router->map('GET', '/hello/[{name}]', function (ResponseFactory $responseFactory, $name = 'nobody') { $response = $responseFactory->createResponse(200); $response->getBody()->write("Hello: $name"); return $response; }); // Handle actual request $request = ServerRequestFactory::fromGlobals(); $response = $router->handle($request); (new SapiEmitter)->emit($response);
With container setup
<?php require __DIR__ . '/../vendor/autoload.php'; use Fas\Autowire\Container; use Fas\Routing\Router; use Laminas\Diactoros\ResponseFactory; use Laminas\Diactoros\ServerRequestFactory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; use Psr\Http\Message\ResponseFactoryInterface; $container = new Container(); $container->set(ResponseFactoryInterface::class, ResponseFactory::class); $router = new Router($container); $router->map('GET', '/hello/[{name}]', function (ResponseFactoryInterface $responseFactory, $name = 'nobody') { $response = $responseFactory->createResponse(200); $response->getBody()->write("Hello: $name"); return $response; }); // Handle actual request $request = ServerRequestFactory::fromGlobals(); $response = $router->handle($request); (new SapiEmitter)->emit($response);
Middlewares
Middlewares attached to Router
are always run, even if the requested route does not exist.
<?php $router = new Router($container); $router->middleware(function ($request, $handler) { return $some_response || $handler->handle($request); }); $router->middleware('some_container_entry_that_is_a_psr_middleware'); $router->middleware(['some_container_entry_that_is_an_object', 'method']); $router->middleware(['some_class_name', 'method']); $router->middleware([$some_object, 'method']); $router->middleware($some_object_that_is_a_psr_middleware); // for invokable objects, use the __invoke method, as it otherwise would be considered // a middlewareinterface object $router->middleware([$some_object_that_is_invokable, '__invoke']);
Groups
Groups can be created for attaching middlewares to multiple routes. There's no prefix mechanism available.
Middlewares attached to groups are only run, if the requested route exists.
<?php require __DIR__ . '/../vendor/autoload.php'; use App\AuthMiddleware; use Fas\Routing\Router; use Laminas\Diactoros\ResponseFactory; use Laminas\Diactoros\ServerRequestFactory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; $router = new Router; // Authenticated routes $authenticated = $router->group(); $authenticated->middleware(AuthMiddleware::class); $$authenticated->map('GET', '/hello/[{name}]', function (ResponseFactory $responseFactory, $name = 'nobody') { $response = $responseFactory->createResponse(200); $response->getBody()->write("Hello: $name"); return $response; }); // Un-authenticated routes $anonymous = $router->group(); $$anonymous->map('GET', '/login', function (ResponseFactory $responseFactory) { $response = $responseFactory->createResponse(200); $response->getBody()->write("Please login first"); return $response; }); // Handle actual request $request = ServerRequestFactory::fromGlobals(); $response = $router->handle($request); (new SapiEmitter)->emit($response);
Compiled/cached router without container setup
<?php require __DIR__ . '/../vendor/autoload.php'; use Fas\Routing\Router; use Laminas\Diactoros\ResponseFactory; use Laminas\Diactoros\ServerRequestFactory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; $router = Router::load('/tmp/router.cache.php'); if (!$router) { $router = new Router(); $router->map('GET', '/hello/[{name}]', function (ResponseFactory $responseFactory, $name = 'nobody') { $response = $responseFactory->createResponse(200); $response->getBody()->write("Hello: $name"); return $response; }); $router->save('/tmp/router.cache.php'); } // Handle actual request $request = ServerRequestFactory::fromGlobals(); $response = $router->handle($request); (new SapiEmitter)->emit($response);
Compiled/cached with container setup
<?php require __DIR__ . '/../vendor/autoload.php'; use Fas\Autowire\Container; use Fas\Routing\Router; use Laminas\Diactoros\ResponseFactory; use Laminas\Diactoros\ServerRequestFactory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; use Psr\Http\Message\ResponseFactoryInterface; $container = new Container(); $container->set(ResponseFactoryInterface::class, ResponseFactory::class); $router = Router::load('/tmp/router.cache.php', $container); if (!$router) { $router = new Router($container); $router->map('GET', '/hello/[{name}]', function (ResponseFactoryInterface $responseFactory, $name = 'nobody') { $response = $responseFactory->createResponse(200); $response->getBody()->write("Hello: $name"); return $response; }); $router->save('/tmp/router.cache.php'); } // Handle actual request $request = ServerRequestFactory::fromGlobals(); $response = $router->handle($request); (new SapiEmitter)->emit($response);
Whoops error response using container
composer require filp/whoops
require __DIR__ . '/../vendor/autoload.php'; use Fas\Autowire\Container; use Fas\Routing\Router; use Fas\Routing\WhoopsMiddleware; use Laminas\Diactoros\ResponseFactory; use Laminas\Diactoros\ServerRequestFactory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; use Psr\Http\Message\ResponseFactoryInterface; $container = new Container(); $container->set(ResponseFactoryInterface::class, ResponseFactory::class); $container->set(WhoopsMiddleware::class, [WhoopsMiddleware::class, 'withStackTrace']); $router = new Router($container); $router->middleware(WhoopsMiddleware::class); $router->map('GET', '/hello/[{name}]', function (ResponseFactoryInterface $responseFactory, $name = 'nobody') { $response = $responseFactory->createResponse(200); $response->getBody()->write("Hello: $name"); return $response; }); // Handle actual request $request = ServerRequestFactory::fromGlobals(); $response = $router->handle($request); (new SapiEmitter)->emit($response);
Whoops without container
require __DIR__ . '/vendor/autoload.php'; use Fas\Routing\Router; use Fas\Routing\WhoopsMiddleware; use Laminas\Diactoros\ResponseFactory; use Laminas\Diactoros\ServerRequestFactory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; $router = new Router(); $router->middleware(static function (ServerRequestInterface $request, RequestHandlerInterface $handler, ResponseFactory $responseFactory) { return WhoopsMiddleware::withStackTrace($responseFactory)->process($request, $handler); }); $router->map('GET', '/hello/[{name}]', static function (ResponseFactory $responseFactory, $name = 'john doe') { $response = $responseFactory->createResponse(200); $response->getBody()->write(json_encode(['name' => $name])); return $response ->withHeader('Content-Type', 'application/json'); }); // Handle actual request $request = ServerRequestFactory::fromGlobals(); $response = $router->handle($request); (new SapiEmitter)->emit($response);