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

ActiveLibrary[Framework](/categories/framework)

model/router
============

Routing module for ModEl Framework

v0.2.39(2mo ago)04841PHP

Since Oct 23Pushed 2mo agoCompare

[ Source](https://github.com/model-composer/router)[ Packagist](https://packagist.org/packages/model/router)[ RSS](/packages/model-router/feed)WikiDiscussions master Synced yesterday

READMEChangelogDependencies (13)Versions (60)Used By (1)

ModEl Router
============

[](#model-router)

A standalone, framework-agnostic PHP router with bidirectional routing support, multi-field URL segments, and relationship resolution.

Features
--------

[](#features)

- **Modern route syntax** with `:parameter` notation
- **Multi-field segments**: `/users/:name-:surname`
- **Relationship fields**: `/products/:category.name/:id-:name`
- **Bidirectional routing**: Parse URLs and generate URLs
- **Database integration** via dependency injection
- **Framework-agnostic**: Works as a standalone package

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

[](#installation)

The router is designed as a standalone package. You can use install it via Composer:

```
composer require model/router
```

Basic Usage
-----------

[](#basic-usage)

### 1. Create Router providers

[](#1-create-router-providers)

```
use \Model\Router\AbstractRouterProvider;

class RouterProvider extends AbstractRouterProvider {
    public function getRoutes(): void {
        return [
            [
                'pattern' => '/pages/:name',
                'controller' => 'PageController',
                'options' => [
                    'entity' => [
                        'table' => 'pages',
                    ],
                ],
            ],
            [
                'pattern' => '/users/:name-:surname',
                'controller' => 'UserController',
                'options' => [
                    'entity' => [
                        'table' => 'users',
                    ],
                ],
            ],
        ];
    }
}

### 2. Create Router

```php
use Model\Router\Router;

// If your route do not use database lookups
$router = new Router();

// If they use database lookups, provide a Resolver instance
$resolver = new YourDatabaseResolver(); // Implement the Resolver interface
$router = new Router($resolver);
```

### 3. Match Incoming URLs

[](#3-match-incoming-urls)

```
$url = '/pages/about-us';
$result = $router->match($url);

if ($result) {
	$controller = $result['controller']; // 'PageController'
	$params = $result['params']; // ['id' => 5] (from database lookup)
}
```

### 4. Generate URLs

[](#4-generate-urls)

```
// Generate URL with ID
$url = $router->generate('PageController', 5);
// Result: /pages/about-us

// Generate URL with explicit parameters
$url = $router->generate('UserController', [
	'name' => 'John',
	'surname' => 'Doe',
]);
// Result: /users/john-doe
```

Route Syntax
------------

[](#route-syntax)

### Simple Parameters

[](#simple-parameters)

```
[
    'pattern' => '/pages/:name',
    'controller' => 'PageController',
    'options' => [
        'entity' => [
            'table' => 'pages',
        ],
    ],
]
```

URL: `/pages/about-us` → Looks up page with `name = 'about-us'`

### Numeric IDs

[](#numeric-ids)

```
[
    'pattern' => '/pages/:id',
    'controller' => 'PageController',
]
```

URL: `/pages/123` → Directly matches ID 123

### Multiple Fields in One Segment

[](#multiple-fields-in-one-segment)

```
[
    'pattern' => '/pages/:name-:surname',
    'controller' => 'UserController',
    'options' => [
        'entity' => [
            'table' => 'users',
        ],
    ],
]
```

URL: `/users/john-doe-smith` → Tries combinations:

- `name='john'` AND `surname='doe-smith'`
- `name='john-doe'` AND `surname='smith'`

### Relationship Fields

[](#relationship-fields)

```
[
    'pattern' => '/products/:category.name/:id-:name',
    'controller' => 'ProductController',
    'options' => [
        'entity' => [
            'table' => 'products',
        ],
    ],
]
```

URL: `/products/electronics/123-laptop` → Looks up:

1. Category with `name = 'electronics'`
2. Product with `id = 123` AND `name = 'laptop'`

### Multiple Dynamic Segments

[](#multiple-dynamic-segments)

Multiple direct (non-relationship) dynamic segments in the same pattern are combined into a single query: every segment's field value is applied as a filter on the target entity at the same time.

```
[
    'pattern' => '/:type/products/:name',
    'controller' => 'ProductController',
    'options' => [
        'entity' => [
            'table' => 'products',
        ],
    ],
]
```

URL: `/electronics/products/laptop` → Looks up a product with `type = 'electronics'` AND `name = 'laptop'` in one query. If any segment contains the primary key (e.g. `:id`) and it is extractable from the URL, that direct fetch still wins and other segments are skipped.

Route Options
-------------

[](#route-options)

### Available Options

[](#available-options)

- `table` (string): Database table for lookups
- `primary` (string): Primary key field name (default: 'id')
- `relationships` (array): Relationship configuration
- `case_sensitive` (bool): Case-sensitive matching (default: false)
- `tags` (array): Additional metadata for route filtering
- `lowercase` (bool): Convert generated URLs to lowercase (default: true)

### Example with All Options

[](#example-with-all-options)

```
[
    'pattern' => '/blog/:category.name/:id-:slug',
    'controller' => 'BlogController',
    'options' => [
        'entity' => [
            'table' => 'blog_posts',
        ],
        'case_sensitive' => false,
        'tags' => [
            'lang' => 'en',
            'type' => 'public',
        ],
        'lowercase' => true,
]
```

URL Generation with Tags
------------------------

[](#url-generation-with-tags)

Generate URLs for specific route variants using tags:

```
// Generate for specific language
$url = $router->generate('PageController', 5, ['lang' => 'en']);
// Result: /pages/about-us

$url = $router->generate('PageController', 5, ['lang' => 'it']);
// Result: /pagine/chi-siamo
```

Advanced Features
-----------------

[](#advanced-features)

### Custom URL Encoding

[](#custom-url-encoding)

The router automatically converts field values to URL-friendly format:

- Converts to lowercase
- Replaces any disallowed character (whitespace, punctuation like `'`, `&`, `!`, ...) with a dash, then collapses consecutive dashes — this keeps the generator aligned with the matcher, which splits URL segments on `-` and turns them into `%` LIKE wildcards (so `"L'Araba Fenice Hotel & Resort"` generates `l-araba-fenice-hotel-resort` and matches back)
- Supports Unicode characters (Cyrillic, Chinese, etc.)

### Caching

[](#caching)

The UrlGenerator caches database lookups during URL generation to minimize queries. Routes are also cached after first loading.

### Combination Algorithm

[](#combination-algorithm)

For multi-field segments, the router generates all possible word distributions and tries each until finding a match.

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance84

Actively maintained with recent releases

Popularity16

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity40

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 ~3 days

Total

59

Last Release

81d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/17624354?v=4)[Zorinik](/maintainers/Zorinik)[@Zorinik](https://github.com/Zorinik)

---

Top Contributors

[![Zorinik](https://avatars.githubusercontent.com/u/17624354?v=4)](https://github.com/Zorinik "Zorinik (73 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[laravel/dusk

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

1.9k39.6M299](/packages/laravel-dusk)[nineinchnick/edatatables

Grid widget for the Yii Framework, wrapper for the DataTables jQuery plugin

173.2k](/packages/nineinchnick-edatatables)[link-cloud/fast-hyperf

LinkCloud Fast Hyperf

241.2k1](/packages/link-cloud-fast-hyperf)

PHPackages © 2026

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