2017 © Pedro Peláez
 

library routing

a fast and flexible HTTP Router

image

devlibs/routing

a fast and flexible HTTP Router

  • Tuesday, October 24, 2017
  • by Razon
  • Repository
  • 3 Watchers
  • 6 Stars
  • 41 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 2 Versions
  • 0 % Grown

The README.md

PHP Router

Build Status Coverage Status Latest Stable Version Total Downloads License, (*1)

A fast, flexible and scalable HTTP router for PHP., (*2)

Features

  • Grouping and nested group
  • Easy to design RESTful API
  • Full Tests
  • Flexible and scalable
  • No third-party library dependencies
  • Named Param Placeholder
  • Detect all request methods of the specify path
  • Straightforward documentation

Requirements

  • PHP - 7.0, 7.1, 7.2 and master are tested.

Install

composer require devlibs/routing:1.0.0

Documentation

include '/path-to-vendor/autoload.php';

use DevLibs\Routing\Router;

// create an router instance
$settings = [
    'middlewares' => [
        'DebugMiddleware',
    ],
];
$router = new Router($settings);

Register handler

Router::handle($method, $path, $handler, $settings = null);
  • method - string or array, case-sensitive, such as GET, GET|POST(split by |, without space), ['GET', 'POST']
  • path - the path MUST start with slash /, such as /, /users, /users/<username>.
  • handler - mixed, whatever you want.
  • settings - user-defined settings.

Examples, (*3)

Method Path Handler Matched Unmatched
GET / handler GET / POST / get /
GET|POST /users handler GET /users POST /users
['GET', 'POST'] /merchants handler GET /merchants POST /merchants
GET /users/<username> handler GET /users/foo GET /users/bar
GET /orders/<order_id:\d+> handler GET /orders/123456 GET /orders/letters

It also provides a few shortcuts for registering handler:, (*4)

  • Router::delete
  • Router::get
  • Router::post
  • Router::put
$router->get('/', 'handler');

$router->handle('GET|POST', '/users', 'handler');

$router->handle(['GET', 'POST'], '/merchants', 'handler');

$router->get('/users/<username>', 'handler');

$router->get('/orders/<order_id:\d+>', 'handler');

Dispatch request

Router::dispatch($method, $path);
  • method - request method, case-sensitive.
  • path - URI path

If matched, an Route instance which implements RouteInterface will be returns, null otherwise., (*5)

$path = '/users/baz';
$route = $router->dispatch(Router::METHOD_GET, $path);
if (is_null($route)) {
    throw new \Exception('404 Not Found');
}

// handle requset
$handler = $route->handler(); // 'handler'
$params = $route->params(); // ['username' => 'baz']
$settings = $route->settings(); // $settings

Route

Class Route implements RouteInterface, provides some basic methods., (*6)

You can also define your own Route class via the following code snippet:, (*7)

Router::$routeClassName = 'namespace\MyRoute';

RouteInterface

Route class MUST implements this interface, see RouteInterface for more detail., (*8)

Named Params Placeholder

As the examples shown above, Router has ability to detect the param's value of the path., (*9)

In general, an placeholder pattern MUST be one of <name> and <name:regex>, it will be converted to ([^/]+) and (regex) respectively. You can also change it via replace the Router::$replacePatterns and Router::$replacements., (*10)

Pattern Path Matched Params
/guests/<name> /guests/小明 YES ['name' => '小明']
/guests/<name:\w+> /guests/foo YES ['name' => 'foo']
/guests/<name:\w+> /guests/小明 NO
/orders/<order_id:\d+> /orders/123 YES ['order_id' => '123']
/orders/<order_id:\d+> /orders/letters NO
/posts/<year:\d{4}>/<month:\d{2}>/<title> /posts/2017/10/hello-world YES ['year' => '2017', 'month' => '10', title' => 'hello-world']
/posts/<year:\d{4}>/<month:\d{2}>/<title> /posts/201/10/hello-world NO
/posts/<year:\d{4}>/<month:\d{2}>/<title> /posts/2017/9/hello-world NO
/posts/<year:\d{4}><month:\d{2}>/<title> /posts/201710/hello-world YES ['year' => '2017', 'month' => '10', title' => 'hello-world']

Settings

You can extend Router via settings, such as param's default value and middleware etc, but this topic are out of scope of this document., (*11)

Grouping

Grouping is an powerful feature of Router for separating modules or API's versions. And this library also implements this feature, it allows nested grouping., (*12)

Router::group($prefix, array $settings = []);
  • prefix - group prefix, it MUST NOT contains slash /.
  • settings - settings for extending, it will inherits parent's settings.
// grouping
$v1Settings = [
    'version' => '1',
    'middlewares' => [
        'AuthMiddleware',
    ],
];
$v1 = $router->group('v1', $v1Settings);
$v1->get('/hello', 'hello');
$route = $router->dispatch(Router::METHOD_GET, '/v1/hello'); // matched
/**
 * [
 *     'version' => '1',
 *     'middlewares' => [
 *         'DebugMiddleware',
 *         'AuthMiddleware',
 *     ],
 * ];
 */
 var_dump($route->settings());
// nested group
$v1Users = $v1->group('users');
$v1Users->get('/', 'users');
$v1Users->get('/<name>', 'user profile');
$route = $router->dispatch(Router::METHOD_GET, '/v1/users'); // matched
$route = $router->dispatch(Router::METHOD_GET, '/v1/users/bar'); // matched

RESTful API

As the examples shown above, it is obviously easy to design a RESTful API application., (*13)

$router->get('/products', 'products');
$router->post('/products', 'create product');
$router->get('/products/<product_id:\d+>', 'product detail');
$router->put('/products/<product_id:\d+>', 'update product');
$router->delete('/products/<product_id:\d+>', 'delete product');

Detect methods

In consideration of OPTIONS request, it provides an API for detecting all valid methods of the specify URI path., (*14)

Route::getAllowMethods($path, $methods = null);
  • path - request URL path
  • methods - Router::$methods defined some common request methods, but it does not include all request methods, you can specify the methods if the key method is not one of the Router::$methods.
$allowMethods = $router->getAllowMethods('/merchants'); // ['GET', 'POST']

FAQ

Package Not Found

Please add the following repository into repositories when composer complains about that Could not find package devlibs/routing ...., (*15)

{
    "type": "git",
    "url": "https://github.com/devlibs/routing.git"
}

The Versions

24/10 2017

dev-master

9999999-dev https://github.com/devlibs/routing

a fast and flexible HTTP Router

  Sources   Download

BSD-3-Clause

The Requires

  • php ^7.0

 

The Development Requires

by Razon Yang

http routing router restful api

24/10 2017

1.0.0

1.0.0.0 https://github.com/devlibs/routing

a fast and flexible HTTP Router

  Sources   Download

BSD-3-Clause

The Requires

  • php ^7.0

 

The Development Requires

by Razon Yang

http routing router restful api