a simple, fast and powerful PHP router.
- Simple Syntax
- Light Weight (single file, ~160 LOC)
- Feature Full
- Tested & Fast
Table of contents
- Installation
- Hello World
- Routes
- Callbacks
- Prefixing Routes (grouping)
- Middleware
- No Match
- Serving Static Files
- Examples
- Tests
require('newrouter.php');
PHP >= 5.3
require('newrouter.php');
$router = new NewRouter();
$router->route('GET /', function(){
echo 'Hello World!';
});
$router->dispatch();
Routes can be added by route()
method. First argument of this method can be a string combined of HTTP method and URL path and second argument is a callback for the specified route.
$router->route('GET /some/path', function(){});
$router->route('POST /some/path', function(){});
$router->route('PUT /some/path', function(){});
Routes will be tested in the same order they are added.
Not specifying a method will match all HTTP methods.
$router->route('/some/path', function(){}); // this will match GET, POST, PUT, DELETE, etc.
Use :parameterName:
syntax to define parameterized routes. parameterName
will be available in arguments passed to callback function.
$router->route('GET /user/:id:', function($request){
// this route will match:
// http://site.com/user/123
// http://site.com/user/abc
// etc.
echo 'user id is ' . $request->params['id']; // id is either 123 or abc
});
You can use below patterns in routings.
Pattern | Meaning | Example Route | Example Match |
---|---|---|---|
* | Anything or nothing | GET /users/* |
site.com/users/ site.com/users/profile site.com/users/profile/images |
+ | Anything but not empty | GET /users/+ |
site.com/users/profile site.com/users/profile/images |
:param: | Anything except / | GET /users/:id: |
site.com/users/profile site.com/users/123 |
Route callbacks can be a Closure, a Callable string or an instance of NewRouter
.
// closure example
$router->route('GET /', function(){
// this will be executed on GET /
});
// class method example
class Foo {
static public function bar() {
// this will be executed on GET /
}
}
$router->route('GET /', 'Foo::bar');
See Prefixing Routes for router instance as callback example.
Return value of callback can change routing behavior. An explicit True
tells NewRouter to continue trying to match next routes.
An implicit False
or Null
means next routes should be stopped.
Note: Not returning anything inside a callback is same as returning Null
.
An instance of stdClass
will be passed to callbacks when a route is matched. Below is list of defined properties in this object.
Property | Description |
---|---|
params | An associative array where keys are captured parameters when using parameterized routes. See Parameterized routing for example. |
url | The URL part that route has matched. |
path | The whole URI without queries. |
Note: Callbacks can capture $request
by reference and manipulate it. See Middleware for more.
A route can have multiple callbacks. Callbacks will be executed in the same order they are added.
$router->route('GET /user/profile', $callback1, $callback2, $callback3);
In above example, callback1 is executed first. Then if it returns true, callback2 gets executed and so on. This is useful for use cases like authorization, see below example.
$isRequestAuthorized = function() {
// do checkings here and return true or false
}
$showUserProfile = function() {
// show profile here
}
$router->route('GET /user/profile', $isRequestAuthorized, $showUserProfile);
By passing an instance of NewRouter
as callback, you can delegate all routes to that instance. This is useful when prefixing/grouping routes.
// define a router for user APIs
$userRouter = new NewRouter();
$userRouter->route('GET /', function(){
// this route is prefixed with /users/
});
$userRouter->route('GET /profile/:id:', function($request){
// this route is prefixed with /users/
});
// define the main router
$mainRouter = new NewRouter();
// delegate all requests to /users/* to $userRouter
$mainRouter->route('/users/*', $userRouter); // prefix $userRouter with /users/ path
//define other routes
$mainRouter->dispatch();
In above example routes like /users/
and /users/profile/123
will be handled by userRouter
.
You can omit route string and only pass callbacks. This kind of callbacks will get executed on all requests.
$router->route(function(){}); // this will get executed on all requests
This could be useful for uses case like logging and intercepting. Below is an example for parsing JWT token.
$router->route(function(&$request){ // notice the capture by reference
$request->decodedJWT = '{"sub": "1234", "name": "John Doe", "iat": 1516239022}'; // in real-world you need to actually read JWT from headers and decode it
return true; // this is necessary to continue next routes
});
$router->route('GET /profile', function($request) {
// $request->decodedJWT is {"sub": "1234", "name": "John Doe", "iat": 1516239022} here
});
You can also define middlewares for a specific HTTP method. Below example defines a callback which gets executed on all POST requests.
$router->route('POST', function(){
// this is executed on all POST requests
});
You can use a middleware as final route to capture no match. example:
// define routes
$route->route('GET /a', function(){});
$route->route('GET /b', function(){});
// ...
$route->route(function() {
// no routes matched
echo 'invalid route';
});
To serve static files such as images, CSS files, and JavaScript files, use the NewRouterStatic::serve
method. You just need to include newrouterstatic.php
and call NewRouterStatic::serve
as callback for a route. The function signature is:
NewRouterStatic::serve($root, [$options]);
For example, use the following code to serve static files in a directory named asset for routes starting with /public/:
require('newrouterstatic.php');
$router->route('/public/*', NewRouterStatic::serve('./asset/'));
Above example will map all routes to virtual path /public/*
to static files under ./asset/
directory. For example the route /public/logo.jpg
will be mapped as /asset/logo.jpg
.
Note: You can have several static routes.
The second argument of NewRouterStatic::serve
can be an assosiative array of options. The following table describes the keys for options
argument
Key | Description | Default |
---|---|---|
lastModified | A boolean value specifying if last-modified HTTP header should be provided | true |
etag | a Boolean value specifying if etag HTTP header should be provided | true |
See example directory for more detailed examples.
Run below commands in shell to run all tests (210 tests).
cd test
php index.php
Run performance tests only
php performance.php
- import/export routes
- regex patterns
- numbers only pattern
- JSON parser middleware
- CORS middleware