Flexible PSR-7 compliant HTTP router
▄▄ █▀▀▄█░░█▄ ▄▄▄▄▀▀▀▀▀▀▄ ▀▄░░██░░█ █▀▀▀▀▀▓▓▓▓▓▓▒▓▄▄▓▀▄ ▄▄▄▄▄▄ █▄ ▄▄█░░▀▄░█ ▄▄█▀▄▄▀▀█▒▒▒▄▄▀░▀▀██ ▄█▀▀▀▀▀▀██▓█ █░▀█░░█░█▀▀▄▄█░░░▄▀▀▀▀░░░░░░░█ ▄█▄▄▄░░░▒▒▒▀█▓█ ▀▄░█▀█▀▀█▀▄█▄▄▄▀░░░░▀▀█▀▀██░█ ▀▀▄▓▓▓▒▒█▄▀▄ ▄▄█▀▀▄░░░█ █░░░░░░ ▀███░░░█▄ ▀▄▄▓░▒▒▀█▄█▀▀▀▀▒▀█▄█▀░░█▀▀▀▀▀░█░░░░░░░░░░░▄░█ ▀▀▄▄▓▓░░░░░▓▓▓▓▄█ ▀▄▄░▀░░░░░░░░░▄▄▄▄▄▄▄▄▄▄▀▀ ▀▄▓▓▓▓▓▄▄▄▀ █▓▒░░░░░░░░░░░█▄▀▀▀█▄▄▄▄▄▄▄ ▀▀▀▀▀ ▄▀█░▓▒░░░░▄░░░█░▀░▄▄░░█▒▒▒▒▒▒▒█ ▄▄▄▀▀░░░░░░░░▄██▀▀▀▀▀▀█▀░░█▀▀▀▄▄▄▀ DASH █░░░░░▄▄▀█▄▄▄▀▀ █░░░█ █░░▄▄█▒▒▄▀ █░▄▀ ▀▀▀ ▀▀▀ ▀
Dash is a router which was initially meant to be a router for Zend Framework 3, but by now evolved into its very own package. It has a dependency on ZF's ServiceManager, but purely for its plugin manager implementation.
Dash is supposed to be used with a dependency container, but can in theory be used without one. In the average case where you are using Dash with another framework which supplies you a dependency container, there is a file placed in the config directory, which includes all factories which have to be registered. These factories assume that your container also supplies a config array via the name "config". For specific contents of it, refer to the examples below.
Withint your application, you can easily retrieve the dependency config by instantiating
Dash\ConfigProvider. Since it
implements an __invoke() method, it can be used with config managers like expressive-config-manager.
Route configuration is greatly simplified from ZF2, routes now have an (optional) 3 key indexed array as the first 3 parameters, the format for the shortcut parameters are:
[path, defaults, methods]
This may feel counter intuitive, but the idea is that the most frequently changed parameter appears earliest in the order so that when defining child routes you can skip parameters you wish to inherit.
path, will expect a string, whereas
defaults will expect an array and
method will expect either an array of
methods this route should match, a single method in a string, or a string of
'*' for all methods. An empty string
will match no methods. Currently, passing no method defaults to
Along with the indexed shortcut parameters, named configuration can also be passed using key value pairs:
[ 'path' => '/foo', 'defaults' => ['action' => 'bar', 'controller' => 'FooController'], 'methods' => ['get', 'post'] ]
Parameters and named values can be mixed, although the first 3 indexed items will always to be presumed to be the parameters as ordered above.
Child routes can be simply defined in the
children key of the configuration of the parent route:
'dash' => [ 'routes' => [ 'user' => ['/user', ['action' => 'index', 'controller' => 'UserController'], 'children' => [ 'create' => ['/create', ['action' => 'create'], ['get', 'post']], 'edit' => ['/edit/:id', ['action' => 'edit'], ['get', 'post'], 'constraints' => ['id' => '\d+']], 'delete' => ['/delete/:id', ['action' => 'delete'], 'get', 'constraints' => ['id' => '\d+']], ]], ], ],
The router no longer has mulitple route types, instead the
Generic route handles all aspects of HTTP routing.
Instead of specificing the route type in the configuration, the router now knows how to handle all routes based
solely on the configuration.
For example, if you want a given route only to match a specific hostname, simply define the correct key value pair in that route's configuration:
'user' => ['/user', ['action' => index', 'controller' => 'UserController'], 'get', 'hostname' => 'login.example.com']
Similarly, if a given route should only match the https protocol:
'user' => ['/user', ['action' => index', 'controller' => 'UserController'], 'get', 'secure' => true]
One confusion that's anticipate to be a minor problem is the confusion of how to overload a given route parameter from within a different module. This is easily achieved by defining the relevant key\value in the configuration that is intended to override the route. Overwriting a route parameter by the shortcut key will not take effect because it will only be added to the end of the configuration array
Module A 'user' => ['/user', ['action' => index', 'controller' => 'UserController'], 'get']
Module B 'user' => ['path' => '/userinfo']
/user now will no longer match, but
/userinfo will match in it's place.
When doing performance-dependent changes, make sure to compare the benchmarks between master and your branch. To run them, execute the following command:
php vendor/bin/athletic -p benchmark -b vendor/autoload.php