PHPackages                             brickhouse/routing - 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. [Framework](/categories/framework)
4. /
5. brickhouse/routing

ActiveLibrary[Framework](/categories/framework)

brickhouse/routing
==================

Routing mechanism for Brickhouse applications

070PHPCI failing

Since Jan 24Pushed 1y ago1 watchersCompare

[ Source](https://github.com/brickhouse-php/routing)[ Packagist](https://packagist.org/packages/brickhouse/routing)[ RSS](/packages/brickhouse-routing/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

Brickhouse Routing
==================

[](#brickhouse-routing)

This library is a regex-based routing mechanism for PHP applications. It is heavily based on nikic' [FastRoute](https://github.com/nikic/FastRoute) project.

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

[](#installation)

To install the library, you need to require the package via composer:

```
composer require brickhouse/routing
```

Usage
-----

[](#usage)

To add routes to the dispatcher, you can create a `RouteCollector` like so:

```
use Brickhouse\Routing;

$collector = new RouteCollector();
$collector->addRoute('GET', '/', fn() => 'Hello World!');
$collector->addRoute('GET', '/posts/:id', fn() => render_post());
$collector->addRoute('POST', '/posts', fn() => create_post());
```

The collector can then be passed to a dispatcher, which can match the routes:

```
$dispatcher = new Dispatcher($collector);

$route = $dispatcher->dispatch('GET', '/');
```

When a route is matched, `$route` will be an array of the route handler, as well as the parameters in the route. If no route was matched, `$route` is `null`.

### Defining routes

[](#defining-routes)

#### Required parameters

[](#required-parameters)

Parameters can be defined by adding a colon to the beginning of a route segment, like so:

```
$collector->addRoute('GET', '/posts/:id', '...');
```

When the route is matched, the captured parameter value will be returned in the dispatched route:

```
[$handler, $parameters] = $dispatcher->dispatch('GET', '/posts/routing');

echo $parameters;

// ['id' => 'routing']
```

You may define as many parameters in a single route as required:

```
$collector->addRoute('GET', '/users/:user/posts/:post', '...');
```

Route parameters names consist of alphanumeric (`[A-Za-z0-9]`) characters and underscores (`_`).

#### Optional parameters

[](#optional-parameters)

Parameters can also be marked as optional, allowing the route to be dispatched by multiple routes. Optional parameters are defined by placing a `?`-mark after the colon:

```
$collector->addRoute('GET', '/user/:?id', '...');
```

When the parameter is omitted from the matched, it will be set as `null` in the matched route:

```
[$handler, $parameters] = $dispatcher->dispatch('GET', '/user');

echo $parameters;

// ['id' => null]
```

#### Catch-all parameters

[](#catch-all-parameters)

Parameters can be extended to catch all subsequent segments in the path. Catch-all parameters are defined by replacing the colon with an asterisk (`*`):

```
$collector->addRoute('GET', '/posts/*slug', '...');
```

When using a catch-all parameter, all subsequent segments are returned as a single string.

```
$dispatcher->dispatch('GET', '/posts/a');
// $parameters => ['slug' => 'a']

$dispatcher->dispatch('GET', '/posts/a/b');
// $parameters => ['slug' => 'a/b']

$dispatcher->dispatch('GET', '/posts/a/b/c');
// $parameters => ['slug' => 'a/b/c']
```

Catch-all parameters also require a value to be given before matching:

```
$route = $dispatcher->dispatch('GET', '/posts');
// $route => null
```

To allow the catch-all to match routes without giving the parameter, you can mark it as optional:

```
$collector->addRoute('GET', '/posts/*?slug', '...');

// ...

$dispatcher->dispatch('GET', '/posts');
// $parameters => ['slug' => null]

$dispatcher->dispatch('GET', '/posts/a');
// $parameters => ['slug' => 'a']
```

#### Custom pattern constraints

[](#custom-pattern-constraints)

You may write your own constraints for route parameters using regular expressions. Constraints are defined per-argument and can be written like so:

```
$collector->addRoute('GET', '/user/:user_id', '...', ['user_id' => '\d+']);
```

This limits which values can be matched with the route. If the route doesn't match, it'll continue looking for one that does.

```
$route = $dispatcher->dispatch('GET', '/user/423');
// $route => ['...', ['user_id' => '423']]

$route = $dispatcher->dispatch('GET', '/user/admin');
// $route => null
```

Performance
-----------

[](#performance)

Performance is measured using [PHPBench](https://github.com/phpbench/phpbench), running the benchmarks in [bench](./bench/).

All setups are different, but this bench was run on a Mac Mini M4 (16GB, Sequoia 15.3), with PHP 8.4.1 where both XDebug and OPCache disabled.

benchmarksubjectmeanrevstotal`MicroDynamicBenchmark``benchDispatchFirst`0.652μs200000.013s`MicroDynamicBenchmark``benchDispatchLast`6.322μs200000.126s`MicroDynamicBenchmark``benchDispatchUnknown`5.530μs200000.111s`MicroStaticBenchmark``benchDispatchFirst`0.307μs300000.009s`MicroStaticBenchmark``benchDispatchLast`4.394μs300000.132s`MicroStaticBenchmark``benchDispatchUnknown`4.724μs300000.142sLicense
-------

[](#license)

Brickhouse Routing is open-sourced software licensed under the [MIT license](LICENSE.md).

###  Health Score

16

—

LowBetter than 5% of packages

Maintenance32

Infrequent updates — may be unmaintained

Popularity8

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity16

Early-stage or recently created project

 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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/89e99714610675e29eb832627ab917dabde2f35dc0246eb7c46f68d109136efc?d=identicon)[maxnatamo](/maintainers/maxnatamo)

---

Top Contributors

[![maxnatamo](https://avatars.githubusercontent.com/u/5898152?v=4)](https://github.com/maxnatamo "maxnatamo (27 commits)")

### Embed Badge

![Health badge](/badges/brickhouse-routing/health.svg)

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

###  Alternatives

[laravel/telescope

An elegant debug assistant for the Laravel framework.

5.2k67.8M192](/packages/laravel-telescope)[spiral/roadrunner

RoadRunner: High-performance PHP application server and process manager written in Go and powered with plugins

8.4k12.2M84](/packages/spiral-roadrunner)[nolimits4web/swiper

Most modern mobile touch slider and framework with hardware accelerated transitions

41.8k177.2k1](/packages/nolimits4web-swiper)[laravel/dusk

Laravel Dusk provides simple end-to-end testing and browser automation.

1.9k36.7M259](/packages/laravel-dusk)[laravel/prompts

Add beautiful and user-friendly forms to your command-line applications.

708181.8M596](/packages/laravel-prompts)[cakephp/chronos

A simple API extension for DateTime.

1.4k47.7M121](/packages/cakephp-chronos)

PHPackages © 2026

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