httpsoft/http-router

Simple and fast HTTP request router providing PSR-7 and PSR-15

Maintainers

👁 devanych

Package info

github.com/httpsoft/http-router

Homepage

Documentation

pkg:composer/httpsoft/http-router

Statistics

Installs: 43 759

Dependents: 1

Suggesters: 0

Stars: 7

Open Issues: 1

1.1.1 2024-12-29 22:49 UTC

Requires

Suggests

None

Conflicts

None

Replaces

None

MIT 2fd23a8209c39b501f16989303c10e978599ee8f

routephphttprouterpsr-7http-routerpsr-15

This package is auto-updated.

Last update: 2026-06-29 01:50:55 UTC


README

👁 License
👁 Latest Stable Version
👁 Total Downloads
👁 GitHub Build Status
👁 GitHub Static Analysis Status
👁 Scrutinizer Code Coverage
👁 Scrutinizer Code Quality

This package provides convenient management of HTTP request routing with support for PSR-7 and PSR-15.

Documentation

Installation

This package requires PHP version 7.4 or later.

composer require httpsoft/http-router

Usage

use HttpSoft\Router\RouteCollector;

/**
 * @var mixed $handler
 */

$router = new RouteCollector();

// Defining routes.
$router->get('home', '/', $handler);
$router->post('logout', '/logout', $handler);
$router->add('login', '/login', $handler, ['GET', 'POST']);

// Custom regular expressions for placeholder parameter tokens.
$router->delete('post.delete', '/post/delete/{id}', $handler)->tokens(['id' => '\d+']);

// Generate path '/post/delete/25'
$router->routes()->path('post.delete', ['id' => 25]);
// Generate url '//example.com/post/delete/25'
$router->routes()->url('post.delete', ['id' => 25], 'example.com');
// Generate url 'https://example.com/post/delete/25'
$router->routes()->url('post.delete', ['id' => 25], 'example.com', true);

Set the parameter to the default value.

$router->get('post.view', '/post/{slug}{format}', $handler)
 ->tokens(['slug' => '[\w\-]+', 'format' => '\.[a-zA-z]{3,}'])
 ->defaults(['format' => '.html'])
;

// Generate path '/post/post-slug.html'.
$router->routes()->path('post.view', ['slug' => 'post-slug']);

Tokens of the route enclosed in [...] are considered optional.

$router->get('post.list', '/posts{[page]}', $handler)
 ->tokens(['page' => '\d+'])
;

// '/posts/33'
$router->routes()->path('post.list', ['page' => 33]);
// '/posts'
$router->routes()->path('post.list');

If necessary, you can specify a specific host for route matching.

// Only for example.com
$router->get('page', '/page', $handler)
 ->host('example.com')
;

// Only for subdomain.example.com
$router->get('page', '/page', $handler)
 ->host('subdomain.example.com')
;

// Only for shop.example.com or blog.example.com
$router->get('page', '/page', $handler)
 ->host('(shop|blog).example.com')
;

You can specify routes inside of a group.

$router->group('/post', static function (RouteCollector $router): void {
 // '/post/post-slug'
 $router->get('post.view', '/{slug}', ViewHandler::class)->tokens(['slug' => '[\w-]+']);
 // '/post' or '/post/2'
 $router->get('post.list', '/list{[page]}', ListHandler::class)->tokens(['page' => '\d+']);
});

// The result will be equivalent to:

$router->get('post.view', '/post/{slug}', ViewHandler::class)->tokens(['slug' => '[\w-]+']);
$router->get('post.list', '/post/list{[page]}', ListHandler::class)->tokens(['page' => '\d+']);

Check matching routes.

/**
 * @var mixed $handler
 * @var Psr\Http\Message\UriInterface $uri
 * @var Psr\Http\Message\ServerRequestInterface $request
 */

$router->get('page', '/page/{id}', $handler)->tokens(['id' => '\d+']);

// Match
$route = $router->routes()->match($request->withUri($uri->withPath('/page/11')));
$route->getMatchedParameters(); // ['id' => '11']

// Mismatch
$router->routes()->match($request->withUri($uri->withPath('/page/slug'))); // null