badphp / dispatch
a micro-routing library for PHP
Installs: 661
Dependents: 0
Suggesters: 0
Security: 0
Stars: 530
Watchers: 48
Forks: 104
Open Issues: 0
Requires
- php: >= 8.0.0
Requires (Dev)
- ext-xdebug: *
- phpunit/phpunit: ^10.0
- dev-master
- 11.0.1
- 11.0.0
- 10.3.2
- 10.3.1
- 10.3.0
- 10.2.1
- 10.2.0
- 10.1.1
- 10.1.0
- 10.0.0
- 9.0.1
- 9.0.0
- 8.0.4
- 8.0.3
- 8.0.2
- 8.0.1
- 8.0.0
- 7.0.2
- 7.0.1
- 7.0.0
- 6.1.2
- 6.1.1
- 6.1.0
- 6.0.1
- 6.0.0
- 5.3.0
- 5.2.0
- 5.1.0
- 5.0.1
- 5.0.0
- 4.x-dev
- 4.1.0
- 4.0.9
- 4.0.8
- 4.0.7
- 4.0.6
- 4.0.5
- 4.0.4
- 4.0.3
- 4.0.2
- 4.0.1
- 4.0.0
- 3.5.0
- 3.4.0
- 3.3.4
- 3.3.3
- 3.3.2
- 3.3.1
- 3.3.0
- 3.2.1
- 3.2.0
- 3.1.0
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 2.6.3
- 2.6.2
- 2.6.1
- 2.6.0
- 2.5.1
- 2.5.0
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.3
- 2.3.2
- 2.3.1
- 2.3.0
- 2.2.8
- 2.2.7
- 2.2.6
- 2.2.5
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.0
- 1.x-dev
- 1.1.6
- 1.1.5
- 1.1.4
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- dev-feat/helpers
- dev-develop
This package is auto-updated.
Last update: 2023-05-03 13:36:57 UTC
README
- a tiny library for quick and easy PHP apps
- requires at least PHP 8.x
functions
Below is the list of functions provided by dispatch
.
function dispatch(...$args): void; function route(string $method, string $path, callable ...$handlers): void; function _404(callable $handler = null): callable; function apply(...$args): void; function bind(string $name, callable $transform): void; function action(string $method, string $path, callable ...$handlers): array; function response(string $body, int $code = 200, array $headers = []): callable; function redirect(string $location, int $code = 302): callable; function serve(array $routes, string $reqmethod, string $reqpath, ...$args): callable; function phtml(string $path, array $vars = []): string; function stash(string $key, mixed $value = null): mixed;
Here's a sample of how you'd usually use them in an app.
<?php require 'path/to/dispatch.php'; # This is a named route parameter binding. If a requested URI has a # :name parameter in the matching route (eg. /profiles/:user), the mapped # callback gets executed, and the return value gets used as a replacement # for the named parameter value. bind('user', function (string $username, $db): array { $user = loadUserProfileByUsername($db, $username); return $user; }); # Sample middleware that is applied to all routes. Note that # the middleware function requires the first two params to be $next which # is a callable to the next middleware, and the $params named params # associative array. The $params array is always passed, and not optional. # Other arguments that follow are ones forwarded from the dispatch() call. apply(function (callable $next, array $params, $db) { if (isDeviceRestricted($_SERVER)) { # returning a response here breaks the middleware chain return resource('Forbidden', 403); } # we move on to the next middleware return $next(); }); # Sample middleware that gets applied to all routes, and also uses the # stash() function to store values we'll need later. apply(function ($next) { # stash is a function for storing values that can be accessed # anywhere in your handlers. values stored only lasts within the same # request context. stash('favicon.ico', file_get_contents(__DIR__.'/static/favicon.ico')); return $next(); }); # Sample middleware that gets applied to routes matching # the regular expression argument. apply('^/admin/', function ($next, $params, $db) { # note that because of the named parameter binding above, the # value of $params['user'] is already the loaded user profile if (!isAdmin($params['user'])) { return resource('Forbidden', 403); } return $next(); } # Replace default 404 handler _404(fn() => response(phtml('not-found'), 404)); # Sample route that has a named parameter value. Named parameters gets # passed to the handlers as the first argument as an associative array. # Arguments that follow the named parameters array are values passed through # dispatch(...). route('GET', '/profiles/:user', function (array $params, $db) { # because of the named param binding for user, this will # contain the user profile loaded by the named param handler $user = $params['user']; # the $db argument was forwarded from the dispatch() call below $meta = loadUserMetadata($db, $user['username']); # phtml() is a function that loads a phtml file and populates it with # values from the passed in associative array. return response(phtml(__DIR__.'/templates/profile', ['user' => $user])); }); # Sample route that has no named parameter so it doesn't receive the $params # associative array. Only dispatch() arguments get forwarded to the handler. route('GET', '/index', function ($db) { $users = loadTopUsers($db); return response(phtml(__DIR__.'/templates/index', ['users' => $users])); }); # Sample route that has an inline middleware passed in. Note that the # middleware function should still follow the middleware function signature. route( 'GET', '/favicon.ico', # inline middleware function ($next, $params, $db) { logDeviceAccess($db, $_SERVER); return $next(); }, # this is the main handler function () { # stash is a request-scoped storage return response(stash('favicon.ico')); } ); # App routing entry point. All arguments passed to dispatch get forwarded to # matching route handlers after the named params array. $db = createDatabaseConnection(); dispatch($db);
Once dispatch(...)
is called, it will try to match the current request to any
of the mapped routes via route(...)
. When it finds a match, it will then do the
following sequence:
- Execute all named parameter bindings from
bind(...)
- Execute all global middleware and matching middleware from
apply(...)
- Invoke the handler for the matching route.
Because of this sequence, it means that any transformations done by bind(...)
mappings will have already updated the values inside the $params
array that's
forwarded down the execution chain.
license
MIT