binsoul / net-http-router
Web router implementation for PSR-7 requests
Requires
- php: ^7.0
- binsoul/common: ~1.0@dev
- psr/http-message: ~1.0
Requires (Dev)
- fabpot/php-cs-fixer: ^1.0
- phpunit/phpunit: ^5.0
This package is auto-updated.
Last update: 2024-10-14 22:15:45 UTC
README
This package provides a web router implementation for PSR-7 requests. It uses matchers to extract information from the given request and returns a route object.
Your application can use the information provided by the matching route to dispatch it. A dispatcher is not provided by this package.
Install
Via composer:
$ composer require binsoul/net-http-router
Matcher
A matcher can be a closure, an object with an __invoke method or an object implementing the Matcher interface.
If a matcher decides that the route was found it can optionally set an response:
$router->addMatcher( function (Route $route) { if ($route->getMissingPath() == '/hello') { $route->found(new Response('Hello world!')); } } ); $route = $router->match($request); // http:/domain/hello if ($route->hasResponse()) { echo $route->getResponse(); // Hello world! }
StaticMatcher
The StaticMatcher matches simple paths and sets the provided route parameters of a match.
The following example:
$router->addMatcher( new StaticMatcher( [ '/blog' => ['responder' => 'Blog'] ] ) ); $route = $router->match($request); // http://domain/blog var_export($route->getData());
would output:
array('responder' => 'Blog',)
RegexMatcher
The RegexMatcher matches arbitrary regular expressions. Named capture group are set as parameters of the route.
The following example:
$router->addMatcher( new RegexMatcher( [ '/edit/(?<id>[0-9]+)' => ['responder' => 'Edit'] ] ) ); $route = $router->match($request); // http://domain/edit/1 var_export($route->getData());
would output:
array('id' => 1, 'responder' => 'Edit',)
ParameterMatcher
The ParameterMatcher matches paths with parameter placeholders.
Placeholders can be defined in the following format:
[prefix+][name][=format[(length)]][?]
- Prefix: Any number of characters except "]" and "+" followed by a single "+".
- Name: A single character followed by characters, numbers or "_".
- Format: "=" followed by a defined format name optionally followed a length definition.
- Length: A single number or a number range enclosed in parenthesis.
- Marker: If the definition ends with a single "?" the parameter is optional.
For example the path:
/[year=number(4)][/+month=number(1-2)?]/[name].html
would match:
/2015/09/article.html
/2015/9/article.html
/2015/article.html
Found placeholders are set as parameters of the route. The following example:
$router->addMatcher( new ParameterMatcher( [ '/[year]/[month]/[name].html' => ['responder' => 'Blog'] ] ) ); $route = $router->match($request); // http://domain/2015/09/article.html var_export($route->getData());
would output:
array('year' => '2015', 'month' => '09', 'name' => 'article', 'responder' => 'Blog',)
NamespaceMatcher
The NamespaceMatcher allows to group other matchers under a common path prefix:
The following definition:
$matcher = new NamespaceMatcher( '/admin', [ new StaticMatcher( [ '/' => ['responder' => 'Home'], '/list' => ['responder' => 'List'], ] ), new RegexMatcher( [ '/edit/(?<id>[0-9]+)' => ['responder' => 'Edit'], ] ), ] );
would match:
/admin/
/admin/list
/admin/edit/1
Router
Matchers can be registered either as closures or concrete objects or as strings. If a matcher is registered as a string the provided factory is used to lazily build the matcher object.
$router->addMatcher('AccountMatcher'); $router->setFactory($factory); // will call $factory->buildMatcher('AccountMatcher'); $router->match($request);
Matchers are added to an internal queue which will be processed by the default router in the order they were added to the queue.
For example if the queue is build like:
$router->addMatcher('Foo'); // matches /foo $router->addMatcher('Bar'); // matches /bar $router->addMatcher('Baz'); // matches /baz $router->match($request); // http://domain/foo/bar/baz
The route object will change like this:
Foo is called with missing path = '/foo/bar/baz' and matched path = ''
Bar is called with missing path = '/bar/baz' and matched path = '/foo'
Baz is called with missing path = '/baz' and matched path = '/foo/bar'
Testing
$ composer test
License
The MIT License (MIT). Please see License File for more information.