PHPackages                             wepesi/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. wepesi/routing

ActiveLibrary[Framework](/categories/framework)

wepesi/routing
==============

Simple and lightweight php module to write clean route of a web application

v0.2.2(1y ago)724Apache-2.0PHPPHP &gt;=7.4CI passing

Since Aug 16Pushed 1y ago1 watchersCompare

[ Source](https://github.com/bim-g/wepesi-router)[ Packagist](https://packagist.org/packages/wepesi/routing)[ Docs](https://github.com/bim-g/wepesi-router/issues)[ RSS](/packages/wepesi-routing/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (5)Dependencies (2)Versions (11)Used By (0)

wepesi/routing
==============

[](#wepesirouting)

[![Build Status](https://github.com/bim-g/wepesi-router/actions/workflows/php.yml/badge.svg)](https://github.com/bim-g/wepesi-router/actions) [![Source](https://camo.githubusercontent.com/28266f398847653c9be5fdb8511e270ed43daa72e19d563e73c1d9791f235a75/687474703a2f2f696d672e736869656c64732e696f2f62616467652f736f757263652d62696d672f726f757465722d626c75652e7376673f7374796c653d666c61742d737175617265)](https://github.com/bim-g/wepesi-router) [![Version](https://camo.githubusercontent.com/106895f764f088048ad5ac3cadd78b249c330a5ec49733ceca428774784030bf/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7765706573692f726f7574696e672e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/wepesi/routing) [![Downloads](https://camo.githubusercontent.com/18272aeb57e79818ecb0c07121470320505d9f115775332182901c9391ed7e55/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7765706573692f726f7574696e672e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/wepesi/routing/stats) [![License](https://camo.githubusercontent.com/76e9bbd8fe8a0744be0404974b37b8281234bf8675f26e4ca6db619220e542aa/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7765706573692f726f7574696e672e7376673f7374796c653d666c61742d737175617265)](https://github.com/bim-g/wepesi-router/blob/master/LICENSE)[![Issues](https://camo.githubusercontent.com/690a14476abab39619e09f52d99a1c2d05e20b6e1799a8ebbfd1c73007727c6f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f62696d2d672f7765706573692d726f757465723f7374796c653d666c61742d737175617265)](http://github.com/bim-g/wepesi-router/issues)

A lightweight and simple object oriented PHP Router. Built by *([Boss Ibrahim Mussa](https://www.github.com/bim-g))* and [Contributors](https://github.com/bim-g/wepesi-router/graphs/contributors)

Features
--------

[](#features)

- Supports `GET`, `POST`, `PUT`, `DELETE`,`PATCH` request methods
- [Routing shorthands such as `get()`, `post()`, `put()`, …](#routing-shorthands)
- [Static Route Patterns](#route-patterns)
- Dynamic Route Patterns: [Dynamic PCRE-based Route Patterns](#dynamic-pcre-based-route-patterns) or [Dynamic Placeholder-based Route Patterns](#dynamic-placeholder-based-route-patterns)
- [Optional Route Subpatterns](#optional-route-subpatterns)
- [Subrouting / Group Routing](#Subrouting-/-Groupe-Routing)
- [Allowance of `Class@Method` calls](#classmethod-calls)
- [Before Route Middlewares](#before-route-middlewares)
- [Before Router Middlewares / Before App Middlewares](#before-router-middlewares)
- [API Groupe Routing](#api-groupe-routing)
- [Supports `X-HTTP-Method-Override` header](#overriding-the-request-method)
- [Custom 404](#custom-404)
- [Works fine in subfolders](#subfolder-support)

Prerequisites/Requirements
--------------------------

[](#prerequisitesrequirements)

- PHP 7.4 or greater
- URL Rewriting

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

[](#installation)

Installation is possible using Composer

```
composer require wepesi/routing
```

Demo
----

[](#demo)

A demo is included in the `demo` folder. Serve it using your favorite web server, or using PHP 7.4+'s built-in server by executing `php -S localhost:8080` on the shell. A `.htaccess` for use with Apache is included.

Usage
-----

[](#usage)

Create an instance of `\Wepesi\Routing\Router`, define some routes onto it, and run it.

```
// Require composer autoloader
require __DIR__ . '/vendor/autoload.php';

// Create Router instance
$router = new \Wepesi\Routing\Router();

// Define routes
// ...

// Run it!
$router->run();
```

### Routing

[](#routing)

`Wepesi/routing` supports `GET`, `POST`, `PUT`, `PATCH`, `DELETE` HTTP request methods. Pass in a single request method.

When a route matches against the current URL (e.g. `$_SERVER['REQUEST_URI']`), the attached **route handling function** will be executed. The route handling function must be a [callable](http://php.net/manual/en/language.types.callable.php). Only the first route matched will be handled. When no matching route is found, a 404 handler will be executed.

### Routing Shorthands

[](#routing-shorthands)

Shorthands for single request methods are provided:

```
$router->get('pattern', function() { /* ... */ });
$router->post('pattern', function() { /* ... */ });
$router->put('pattern', function() { /* ... */ });
$router->delete('pattern', function() { /* ... */ });
```

Note: Routes must be hooked before `$router->run();` is being called.

### Route Patterns

[](#route-patterns)

Route Patterns can be static or dynamic:

- **Static Route Patterns** contain no dynamic parts and must match exactly against the `path` part of the current URL.
- **Dynamic Route Patterns** contain dynamic parts that can vary per request. The varying parts are named **subpatterns** and are defined using either Perl-compatible regular expressions (PCRE) or by using **placeholders**

#### Static Route Patterns

[](#static-route-patterns)

A static route pattern is a regular string representing a URI. It will be compared directly against the `path` part of the current URL.

Examples:

- `/about`
- `/contact`

Usage Examples:

```
// This route handling function will only be executed when visiting http(s)://www.example.org/about
$router->get('/about', function() {
    echo 'About Page Contents';
});
```

#### Dynamic Placeholder-based Route Patterns

[](#dynamic-placeholder-based-route-patterns)

This type of Route Patterns are the same as **Dynamic PCRE-based Route Patterns**, but with one difference: they don't use regexes to do the pattern matching but they use the more easy **placeholders** instead. Placeholders are strings surrounded by collumn, e.g. `:name`.

Examples:

- `/movies/:id`
- `/profile/:username`

Placeholders are easier to use than PRCEs, but offer you less control as they internally get translated to a PRCE that matches any character (`.*`).

```
$router->get('/movies/:movieId/photos/:photoId', function($movieId, $photoId) {
    echo 'Movie #' . $movieId . ', photo #' . $photoId;
});
```

Note: `the name of the placeholder should match with the name of the parameter that is passed into the route handling function.`

#### Dynamic PCRE-based Route Patterns

[](#dynamic-pcre-based-route-patterns)

This type of Route Patterns contain dynamic parts which can vary per request. The varying parts are named **subpatterns** and are defined using regular expressions.

Usage Examples:

```
// This route handling function will only be executed when visiting http(s)://www.example.org/movies/3
$router->get('/movies/:id', function($id) {
    echo 'Get a movie by ID:'.$id;
})->with('id','[0-9]+');
```

Commonly used PCRE-based subpatterns within Dynamic Route Patterns are:

- `\d+` = One or more digits (0-9)
- `\w+` = One or more word characters (a-z 0-9 \_)
- `[a-z0-9_-]+` = One or more word characters (a-z 0-9 \_) and the dash (-)
- `.*` = Any character (including `/`), zero or more
- `[^/]+` = Any character but `/`, one or more

When multiple subpatterns are defined, the resulting **route handling parameters** are passed into the route handling 'with` function in the order they are defined in:

```
// http(s)://www.example.org/articles/12-nyiragongo-volcano`
$router->get('/artilces/:id-:name', function($id, $title) {
    echo 'Articles #' . $id . ', title #' . $title;
})
->with('id','[0-9]+')
->with('title','[a-z\0-9]+');
```

This will be like a kind of validation of your parameters.

### Subrouting / Groupe Routing

[](#subrouting--groupe-routing)

Use `$router->group($baseroute, $fn)` to group a collection of routes in to a subroute pattern. The subroute pattern is prefixed into all following routes defined in the scope. e.g. Mounting a callback `$fn` onto `/movies` will prefix `/movies` onto all following routes.

```
$router->group('/movies', function() use ($router) {

    // will result in '/movies/'
    $router->get('/', function() {
        echo 'movies overview';
    });

    // will result in '/movies/id'
    $router->get('/:id', function($id) {
        echo 'movie id ' . $id;
    });

});
```

Nesting of subroutes is possible, just define a second `$router->group()` in the callable that's already contained within a preceding `$router->group()`.

```
$router->group('/articles', function() use ($router) {

    // will result in '/articles/'
    $router->get('/', function() {
        echo 'articles overview';
    });

    //
	$router->group('/themes', function() use ($router) {
	    // will result in '/articles/themes'
	    $router->get('/', function() {
	        echo 'Articles themes overview';
	    });
	    // will result in '/articles/themes/4'
	    $router->get('/:id', function($id) {
	        echo 'Articles themes detail id: ' . $id;
	    });

	});

});
```

### `Class#Method` calls

[](#classmethod-calls)

We can route to the class action like so:

```
$router->get('/users/:id', '\Wepesi\Controller\UserController#get_users_detail');
```

or

```
$router->get('/users/:id', [\Wepesi\Controller\UserController::class,'get_users_detail']);
```

When a request matches the specified route URI, the `get_users` method on the `UserController` class will be executed. The defined route parameters will be passed to the class method.

The method can be static(not-recommend) or non-static (recommend). In case of a non-static method, a new instance of the class will be created.

```
$router->get('/users/profile', \Wepesi\Controller\Users::profile());
```

Note: In case you are using static method, dont pass as string or in array.

### Before Route Middleware

[](#before-route-middleware)

`wepesi/routing` supports **Before Route Middlewares**, which are executed before the route handling is processed.

```
$router->get('/articles/:id', function($id) {
    echo "article id is:".$id;
})->middleware(function($id){
	if(!filter_var($id,FILTER_VALIDATE_INT)){
	    echo "you should provide an integer";
	    exit;
	}
});
```

Route middlewares are route specific, one or middleware can be set and will be executed before route function.

```
$router->get('/admin/:id', function($id) {
    echo "admin id is:".$id;
})->middleware(function($id){
	print_r("First middleware");
})->middleware(function($id){
	print_r("Second middleware");
})->middleware(function($id){
	print_r("Last middleware before Route function");
});
```

### API Groupe Routing

[](#api-groupe-routing)

You can define your API route inside the api method, and will auto complet api route fro you.

```
$router->api('/v1',function() use($router){
    $router->group('/users',function() use($router){
        $router->get('/',[appController::class,'getUsers']);
    });
});
// output
// /api/v1/users
```

### Overriding the request method

[](#overriding-the-request-method)

Use `X-HTTP-Method-Override` to override the HTTP Request Method. Only works when the original Request Method is `POST`. Allowed values for `X-HTTP-Method-Override` are `PUT`, `DELETE`, or `PATCH`.

### Custom 404

[](#custom-404)

The default 404 handler sets a 404 status code and exits. You can override this default 404 handler by using `$router->set404(callable);`

```
$router->set404(function() {
    header('HTTP/1.1 404 Not Found');
    // ... do something special here
});
```

You can also define multiple custom routes e.x. you want to define an `/api` route, you can print a custom 404 page:

```
$router->set404('**)?', function() {
    header('HTTP/1.1 404 Not Found');
    header('Content-Type: application/json');

    $jsonArray = array();
    $jsonArray['status'] = "404";
    $jsonArray['status_text'] = "route not defined";

    echo json_encode($jsonArray);
});
```

Also supported are `Class@Method` callables:

```
$router->set404([appController::class,'notfound']);
```

The 404 handler will be executed when no route pattern was matched to the current URL.

💡 You can also manually trigger the 404 handler by calling `$router->trigger404()`

Integration with other libraries
--------------------------------

[](#integration-with-other-libraries)

Integrate other libraries with `wepesi/routing` by making good use of the `use` keyword to pass dependencies into the handling functions.

```
$view = new \Wepesi\View();

$router->get('/', function() use ($view ) {
    $view->assign('email','ibmussafb@gmail.com');
    $view->assign('github','bim-g');
    $view->display("/profile.php");
});

$router->run();
```

Given this structure it is still possible to manipulate the output from within the After Router Middleware

A note on working with PUT
--------------------------

[](#a-note-on-working-with-put)

There's no such thing as `$_PUT` in PHP. One must fake it:

```
$router->put('/movies/:username', function($username) {
    // Fake $_PUT
    $_PUT  = array();
    parse_str(file_get_contents('php://input'), $_PUT);
    // ...
});
```

Subfolder support
-----------------

[](#subfolder-support)

```
$router->api('/v1',function() use($router){
    include __DIR__.'/router/users.php';
});
```

License
-------

[](#license)

`wepesi/routing` is released under the Apache-2.0 license. See the enclosed `LICENSE` for details.

###  Health Score

29

—

LowBetter than 57% of packages

Maintenance46

Moderate activity, may be stable

Popularity12

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity44

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

Total

5

Last Release

415d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3b7536aed6138da14cfe4d2a295017fd44f2997ee86c689e8aa6276080164cfd?d=identicon)[ibmussa](/maintainers/ibmussa)

---

Top Contributors

[![bim-g](https://avatars.githubusercontent.com/u/16068170?v=4)](https://github.com/bim-g "bim-g (45 commits)")

---

Tags

frameworkphprouterrouting

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  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)
