PHPackages                             il4mb/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. [API Development](/categories/api)
4. /
5. il4mb/routing

ActiveLibrary[API Development](/categories/api)

il4mb/routing
=============

Deterministic routing engine with an HTTP attribute router adapter (priority, fallback, wildcard matching, tracing, and reloadable rules)

0.2.0(5mo ago)066MITPHPPHP ^8.0CI passing

Since Jan 11Pushed 5mo ago1 watchersCompare

[ Source](https://github.com/il4mb/Routing)[ Packagist](https://packagist.org/packages/il4mb/routing)[ RSS](/packages/il4mb-routing/feed)WikiDiscussions main Synced today

READMEChangelog (4)DependenciesVersions (6)Used By (0)

Routing Engine (PHP)
====================

[](#routing-engine-php)

This repository provides a deterministic routing engine that can be embedded into infrastructure-style software:

- HTTP applications (controller routing)
- API gateways and reverse proxies (upstream selection)
- Programmable network services (policy routing)
- Mail servers (message classification and delivery policy)

The project contains both:

- a **protocol-agnostic core** (`src/Engine/*`) with explicit match and decision phases, and
- a **legacy HTTP router** (`src/Router.php`) that compiles attribute routes into the core engine.

The intent is to keep routing decisions explainable, testable, and observable.

Requirements
------------

[](#requirements)

- PHP 8.1+
- Composer (for autoloading)

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

[](#installation)

```
composer require il4mb/routing
```

Quick Start (HTTP Attribute Routes)
-----------------------------------

[](#quick-start-http-attribute-routes)

```
use Il4mb\Routing\Http\Method;
use Il4mb\Routing\Http\Request;
use Il4mb\Routing\Map\Route;
use Il4mb\Routing\Router;

final class AdminController
{
    #[Route(Method::GET, '/admin/home', priority: 50)]
    public function home()
    {
        return 'ok';
    }

    // Fallback route (only used if nothing else matches)
    #[Route(Method::GET, '/{path.*}', fallback: true)]
    public function notFound(string $path, Request $req, Response $res, callable $next)
    {
        return ['error' => 'not_found', 'path' => $path];
    }
}

$router = new Router(options: [
    // Production deployments typically disable this side-effect.
    'manageHtaccess' => false,

    // chain|first|error_on_ambiguous
    'decisionPolicy' => 'first',

    // Enable only while debugging.
    'debugTrace' => true,
]);

$router->addRoute(new AdminController());

$response = $router->dispatch(new Request());
echo $response->send();
```

When `debugTrace=true`, the router stores trace data into:

- `Request::get('__route_trace')`
- `Request::get('__route_decision')`

Using the Core Engine (Protocol-Agnostic)
-----------------------------------------

[](#using-the-core-engine-protocol-agnostic)

The engine routes a `RoutingContext` through a deterministic pipeline.

```
use Il4mb\Routing\Engine\DecisionPolicy;
use Il4mb\Routing\Engine\RouteDefinition;
use Il4mb\Routing\Engine\RouteTable;
use Il4mb\Routing\Engine\RouterEngine;
use Il4mb\Routing\Engine\RoutingContext;
use Il4mb\Routing\Engine\Matchers\HostMatcher;
use Il4mb\Routing\Engine\Matchers\PathPatternMatcher;
use Il4mb\Routing\Engine\Matchers\ProtocolMatcher;

$routes = [
    new RouteDefinition(
        id: 'proxy.payments.eu',
        target: ['cluster' => 'payments-eu'],
        matchers: [
            new ProtocolMatcher('https'),
            new HostMatcher('payments.example.com'),
            new PathPatternMatcher('/v1/**'),
        ],
        priority: 100,
    ),
];

$engine = new RouterEngine(new RouteTable($routes), policy: DecisionPolicy::FIRST);

$ctx = new RoutingContext(protocol: 'https', host: 'payments.example.com', path: '/v1/charge', method: 'GET');
$outcome = $engine->route($ctx);

if ($outcome->ok) {
    $selected = $outcome->decision->selected[0] ?? null;
    // $selected->target contains your adapter payload
}
```

Documentation
-------------

[](#documentation)

- Architecture: [docs/architecture.md](docs/architecture.md)
- Routing model: [docs/routing.md](docs/routing.md)
- HTTP router (legacy adapter): [docs/http.md](docs/http.md)
- HTTP controllers (binding + request/response cookbook): [docs/http-controller.md](docs/http-controller.md)
- Extensions: [docs/extensions.md](docs/extensions.md)

Release notes
-------------

[](#release-notes)

- Changelog: [CHANGELOG.md](CHANGELOG.md)

Examples
--------

[](#examples)

- Gateway-style routing + tracing: [examples/gateway-routing.php](examples/gateway-routing.php)
- Gateway-style middleware pipeline around target execution: [examples/gateway-middleware.php](examples/gateway-middleware.php)
- Hot reload via `PhpRuleLoader` + `RouterEngine::reload()`: [examples/hotreload.php](examples/hotreload.php)
- HTTP attribute routing (basic): [examples/http-basic.php](examples/http-basic.php)
- HTTP attribute routing (header constraints): [examples/http-headers.php](examples/http-headers.php)
- HTTP attribute routing (priority + fallback): [examples/http-priority-fallback.php](examples/http-priority-fallback.php)
- Real HTTP app (public/index.php style): [examples/http-app/README.md](examples/http-app/README.md)

Tests
-----

[](#tests)

Run the lightweight (dependency-free) tests:

```
php -d zend.assertions=1 -d assert.exception=1 tests/run.php
```

Design Philosophy
-----------------

[](#design-philosophy)

- Explicit over implicit: matching, ordering, and decision policy are visible.
- Configuration as code: routes can be loaded as typed objects and tested.
- Predictable execution: deterministic tie-breaking (priority → specificity → id).
- Minimal magic: adapters own side-effects; the core engine stays pure.

License
-------

[](#license)

MIT. See [LICENSE](LICENSE).

###  Health Score

32

—

LowBetter than 69% of packages

Maintenance71

Regular maintenance activity

Popularity8

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity37

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.

###  Release Activity

Cadence

Every ~90 days

Total

5

Last Release

177d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/80049379?v=4)[ilham B](/maintainers/il4mb)[@il4mb](https://github.com/il4mb)

---

Top Contributors

[![il4mb](https://avatars.githubusercontent.com/u/80049379?v=4)](https://github.com/il4mb "il4mb (68 commits)")

---

Tags

apideterministicembeddedhttp-serverphprouterservers

### Embed Badge

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

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

###  Alternatives

[exsyst/swagger

A php library to manipulate Swagger specifications

35916.4M7](/packages/exsyst-swagger)[hubspot/api-client

Hubspot API client

24016.2M20](/packages/hubspot-api-client)[pocketmine/bedrock-protocol

An implementation of the Minecraft: Bedrock Edition protocol in PHP

172445.0k13](/packages/pocketmine-bedrock-protocol)[botman/driver-telegram

Telegram driver for BotMan

93459.5k6](/packages/botman-driver-telegram)

PHPackages © 2026

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