httpsoft / http-router
Simple and fast HTTP request router providing PSR-7 and PSR-15
Installs: 15 034
Dependents: 1
Suggesters: 0
Security: 0
Stars: 5
Watchers: 4
Forks: 0
Open Issues: 0
Requires
- php: ^7.4|^8.0
- httpsoft/http-runner: ^1.1
Requires (Dev)
- httpsoft/http-message: ^1.1
- phpunit/phpunit: ^9.5
- squizlabs/php_codesniffer: ^3.7
- vimeo/psalm: ^4.9|^5.2
Provides
README
This package provides convenient management of HTTP request routing with support for PSR-7 and PSR-15.
Documentation
Installation
This package requires PHP version 7.4 or later.
composer require httpsoft/http-router
Usage
use HttpSoft\Router\RouteCollector; /** * @var mixed $handler */ $router = new RouteCollector(); // Defining routes. $router->get('home', '/', $handler); $router->post('logout', '/logout', $handler); $router->add('login', '/login', $handler, ['GET', 'POST']); // Custom regular expressions for placeholder parameter tokens. $router->delete('post.delete', '/post/delete/{id}', $handler)->tokens(['id' => '\d+']); // Generate path '/post/delete/25' $router->routes()->path('post.delete', ['id' => 25]); // Generate url '//example.com/post/delete/25' $router->routes()->url('post.delete', ['id' => 25], 'example.com'); // Generate url 'https://example.com/post/delete/25' $router->routes()->url('post.delete', ['id' => 25], 'example.com', true);
Set the parameter to the default value.
$router->get('post.view', '/post/{slug}{format}', $handler) ->tokens(['slug' => '[\w\-]+', 'format' => '\.[a-zA-z]{3,}']) ->defaults(['format' => '.html']) ; // Generate path '/post/post-slug.html'. $router->routes()->path('post.view', ['slug' => 'post-slug']);
Tokens of the route enclosed in [...]
are considered optional.
$router->get('post.list', '/posts{[page]}', $handler) ->tokens(['page' => '\d+']) ; // '/posts/33' $router->routes()->path('post.list', ['page' => 33]); // '/posts' $router->routes()->path('post.list');
If necessary, you can specify a specific host for route matching.
// Only for example.com $router->get('page', '/page', $handler) ->host('example.com') ; // Only for subdomain.example.com $router->get('page', '/page', $handler) ->host('subdomain.example.com') ; // Only for shop.example.com or blog.example.com $router->get('page', '/page', $handler) ->host('(shop|blog).example.com') ;
You can specify routes inside of a group.
$router->group('/post', static function (RouteCollector $router): void { // '/post/post-slug' $router->get('post.view', '/{slug}', ViewHandler::class)->tokens(['slug' => '[\w-]+']); // '/post' or '/post/2' $router->get('post.list', '/list{[page]}', ListHandler::class)->tokens(['page' => '\d+']); }); // The result will be equivalent to: $router->get('post.view', '/post/{slug}', ViewHandler::class)->tokens(['slug' => '[\w-]+']); $router->get('post.list', '/post/list{[page]}', ListHandler::class)->tokens(['page' => '\d+']);
Check matching routes.
/** * @var mixed $handler * @var Psr\Http\Message\UriInterface $uri * @var Psr\Http\Message\ServerRequestInterface $request */ $router->get('page', '/page/{id}', $handler)->tokens(['id' => '\d+']); // Match $route = $router->routes()->match($request->withUri($uri->withPath('/page/11'))); $route->getMatchedParameters(); // ['id' => '11'] // Mismatch $router->routes()->match($request->withUri($uri->withPath('/page/slug'))); // null