PHPackages                             matthiasmullie/router - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. matthiasmullie/router

ActiveLibrary[HTTP &amp; Networking](/categories/http)

matthiasmullie/router
=====================

PSR-15 based router interface on top of FastRoute

1.2.0(1y ago)020MITPHPPHP ^8.1

Since Jun 4Pushed 1y ago1 watchersCompare

[ Source](https://github.com/matthiasmullie/router)[ Packagist](https://packagist.org/packages/matthiasmullie/router)[ Docs](https://github.com/matthiasmullie/router)[ GitHub Sponsors](https://github.com/matthiasmullie)[ RSS](/packages/matthiasmullie-router/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (10)Versions (7)Used By (0)

Router
======

[](#router)

[![Build status](https://camo.githubusercontent.com/f7cc0edbec978dd41bc7bde5ff253baae25f420932488b8d814e4106ced49e38/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d617474686961736d756c6c69652f726f757465722f746573742e796d6c3f6272616e63683d6d61696e267374796c653d666c61742d737175617265)](https://github.com/matthiasmullie/router/actions/workflows/test.yml)[![Code coverage](https://camo.githubusercontent.com/4237b3e81ac676c738369948a378f01e6f83adcd2285ce011bf633819864d0e1/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f67682f6d617474686961736d756c6c69652f726f757465723f7374796c653d666c61742d737175617265)](https://codecov.io/gh/matthiasmullie/router)[![Latest version](https://camo.githubusercontent.com/2930850d8372229c2a62eee79333f194655dc5ee4fc5c47c0a8ab954e0aa6c3e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d617474686961736d756c6c69652f726f757465723f7374796c653d666c61742d737175617265)](https://packagist.org/packages/matthiasmullie/router)[![Downloads total](https://camo.githubusercontent.com/35c468a26c78d131e90144fa7293e990a158c7ff2284c9d26af9dc86b0d3d833/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d617474686961736d756c6c69652f726f757465723f7374796c653d666c61742d737175617265)](https://packagist.org/packages/matthiasmullie/router)[![License](https://camo.githubusercontent.com/2c70e05fd991628a924b6f07053af2ca1fdf17518b05e98c28dd26334cacbc9c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6d617474686961736d756c6c69652f726f757465723f7374796c653d666c61742d737175617265)](https://github.com/matthiasmullie/router/blob/main/LICENSE)

Installation
------------

[](#installation)

Simply add a dependency on `matthiasmullie/router` to your composer.json file if you use [Composer](https://getcomposer.org/) to manage the dependencies of your project:

```
composer require matthiasmullie/router
```

Usage
-----

[](#usage)

### Routes

[](#routes)

This router provides a simple way to map routes (request method + path) to request handlers.

Request handlers are classes that implement [PSR-15](https://www.php-fig.org/psr/psr-15/)'s the `Psr\Http\Server\RequestHandlerInterface` interface, which accept a `Psr\Http\Message\ServerRequestInterface` and return a `Psr\Http\Message\ResponseInterface` object.

This is essentially just a simple PSR-15 layer on top of [FastRoute](https://packagist.org/packages/nikic/fast-route).

It's about as simple as that:

```
use MatthiasMullie\Router\RequestMethods;
use MatthiasMullie\Router\Router;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\ServerRequest;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

// create 2 example request handlers
class RouteOne implements RequestHandlerInterface
{
    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        return new Response(
            200,
            ['Content-Type' => 'application/json; charset=utf-8'],
            json_encode(['message' => 'Hello world']),
        );
    }
}
class RouteTwo implements RequestHandlerInterface
{
    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        return new Response(
            200,
            ['Content-Type' => 'text/html; charset=utf-8'],
            'Hello world',
        );
    }
}

// create router instance and add both routes
$this->router = new Router();
$this->router->addRoute(
    RequestMethods::GET,
    '/one',
    new RouteOne(),
);
$this->router->addRoute(
    RequestMethods::GET,
    '/two',
    new RouteTwo(),
);

// route a request, receive response from the matching request handler
$response = $router->handle(
    new ServerRequest('GET', '/one'),
);
echo $response->getBody(); // outputs: {"message":"Hello world"}
```

### Groups

[](#groups)

For convenient, routes with the same prefix can be bundled together in a group.

Like so:

```
// create router instance and add an individual route
$this->router = new Router();
$this->router->addRoute(
    RequestMethods::GET,
    '/one', // maps to /one
    new RouteOne(),
);

// then 2 more routes with a shared prefix
$group = $this->router->addGroup('/prefix');
$group->addRoute(
    RequestMethods::GET,
    '/two', // maps to /prefix/two
    new RouteTwo(),
);
$group->addRoute(
    RequestMethods::GET,
    '/three', // maps to /prefix/three
    new RouteThree(),
);
```

### Middleware

[](#middleware)

In addition to PSR-15's request handlers, this router also supports PSR-15's `Psr\Http\Server\MiddlewareInterface`, which wrap around a request handler, executing either or both before and after handling the request.

This simplifies logic that is shared between multiple request handlers, like authentication, logging, etc.

Middleware can be added to individual routes, all routes within a group, or simply all routes.

Like this:

```
class Middleware implements MiddlewareInterface {
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        // execute something before handling the request,
        // or manipulate the request object
        $request = $request->withAttribute('middleware', 'Hello world');

        // invoke the handler (or the next middleware, if any)
        // and retrieve the response
        $response = $handler->handle($request);

        // execute something after handling the request,
        // or manipulate the response object
        return $response->withAddedHeader('Content-Type', 'application/json; charset=utf-8);
    }
}

// create router instance and add a route with middleware
$this->router = new Router();
$this->router
    ->addRoute(
        RequestMethods::GET,
        '/one',
        new RouteOne(),
    )
    ->addMiddleware(
        new Middleware(),
    );

// or add a group with middleware that applies to all routes within that group
$this->router
    ->addGroup('/prefix')
    ->addMiddleware(
        new Middleware(),
    )
    ->addRoute(
        RequestMethods::GET,
        '/two',
        new RouteTwo(),
    );

// or add middleware that applies to all routes
$this->router->addMiddleware(
    new Middleware(),
);
```

### Exceptions

[](#exceptions)

By default, any exception that is encountered, either within the request handler/middleware, or as part of routing (e.g. invalid route), will simply be thrown. It is, however, possible to add a custom exception handler, which will catch any exception and return a response.

This can be done by supplying an `MatthiasMullie\Router\ExceptionResponseInterface` instance to the router, e.g. the provided `MatthiasMullie\Router\ExceptionResponse`. This will catch any exception and return a response with the appropriate status code.

This package also comes with a custom `MatthiasMullie\Router\Exception` class that allows including HTTP status codes and headers in the exception.

Example:

```
use MatthiasMullie\Router\Exception;
use MatthiasMullie\Router\ExceptionResponse;

class RouteException implements RequestHandlerInterface
{
    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        throw new Exception('Not Implemented', 501);
    }
}

$this->router = new Router(new ExceptionResponse(new Response()));
$this->router->addRoute(
    RequestMethods::GET,
    '/exception',
    new RouteException(),
);

$response = $router->handle(
    new ServerRequest('GET', '/exception'),
);
// $response now includes the 501 Not Implemented status code & reason phrase
```

License
-------

[](#license)

router is [MIT](http://opensource.org/licenses/MIT) licensed.

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance34

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~14 days

Total

6

Last Release

636d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/cad3300bf52ada70b17962024941977a92a4da8551cbb92493de23c4bbbb5252?d=identicon)[matthiasmullie](/maintainers/matthiasmullie)

---

Top Contributors

[![matthiasmullie](https://avatars.githubusercontent.com/u/312776?v=4)](https://github.com/matthiasmullie "matthiasmullie (7 commits)")

---

Tags

httpmiddlewarerouterpsr-15FastRoute

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/matthiasmullie-router/health.svg)

```
[![Health](https://phpackages.com/badges/matthiasmullie-router/health.svg)](https://phpackages.com/packages/matthiasmullie-router)
```

###  Alternatives

[middlewares/fast-route

Middleware to use FastRoute

96191.1k15](/packages/middlewares-fast-route)[sunrise/http-router

A powerful solution as the foundation of your project.

16249.8k10](/packages/sunrise-http-router)[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28137.8k](/packages/phpro-http-tools)[mezzio/mezzio-authentication

Authentication middleware for Mezzio and PSR-7 applications

121.6M26](/packages/mezzio-mezzio-authentication)[northwoods/router

Fast router for PSR-15 request handlers

161.4k](/packages/northwoods-router)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
