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

ActiveLibrary

jetfirephp/routing
==================

JetFire - Routing

v1.3(9y ago)172271MITPHPPHP &gt;=5.4.0

Since Feb 13Pushed 7y ago1 watchersCompare

[ Source](https://github.com/jetfirephp/routing)[ Packagist](https://packagist.org/packages/jetfirephp/routing)[ RSS](/packages/jetfirephp-routing/feed)WikiDiscussions master Synced 2mo ago

READMEChangelogDependencies (2)Versions (6)Used By (0)

JetFire PHP Routing
-------------------

[](#jetfire-php-routing)

[![SensioLabsInsight](https://camo.githubusercontent.com/cdfaa3505797bd8b95d4e4f24dcf8cc0a0938823f05aa6e8f7f90963ac4d2d2a/68747470733a2f2f696e73696768742e73656e73696f6c6162732e636f6d2f70726f6a656374732f61656238333532342d343462632d343530312d393064632d3138303431636337613834612f6d696e692e706e67)](https://insight.sensiolabs.com/projects/aeb83524-44bc-4501-90dc-18041cc7a84a) [![Build Status](https://camo.githubusercontent.com/43f15c71c2a91fb1b8e2e66ed410377179f3f638c8d378a50583370a12e1df6c/68747470733a2f2f7472617669732d63692e6f72672f6a6574666972657068702f726f7574696e672e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/jetfirephp/routing) [![Scrutinizer Code Quality](https://camo.githubusercontent.com/6266af9cbcc653ecc2c70b961c35ebe8be4443502ce6642b584868de04e81ce1/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6a6574666972657068702f726f7574696e672f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/jetfirephp/routing/?branch=master)

A simple &amp; powerful router for PHP 5.4+

### Features

[](#features)

V1.3

- [Support subdomain](#subdomain)
- [Support group resolver](#group-resolver)

V1.2

- [ClosureTemplate resolver](#closureTemplate-resolver)
- [ControllerTemplate resolver](#controllerTemplate-resolver)
- Possibility to choose a resolver

V1.1

- [Support dependency injection container](#config)
- [Add your custom matcher and dispatcher](#custom-matcher)

V1.0

- Support static &amp; dynamic route patterns
- [Support REST routing](#rest)
- [Support reversed routing using named routes](#named-routes)
- [Uri matcher](#uri-matcher)
- [Array matcher](#array-matcher)
- [Closure resolver](#closure-resolver)
- [Template resolver](#template-resolver)
- [Controller resolver](#controller-resolver)
- [Route Middleware](#middleware)
- [Integration with other libraries](#libraries)

### Getting started

[](#getting-started)

1. PHP 5.4+ is required
2. Install `JetFire\Routing` using Composer
3. Setup URL rewriting so that all requests are handled by index.php

### Installation

[](#installation)

Via [composer](https://getcomposer.org)

```
$ composer require jetfirephp/routing
```

#### .htaccess

[](#htaccess)

```
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.[a-zA-Z0-9\-\_\/]*)$ index.php?url=$1 [QSA,L]
```

### Usage

[](#usage)

Create an instance of `JetFire\Routing\RouteCollection` and define your routes. Then create an instance of `JetFire\Routing\Router` and run your routes.

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

// Create RouteCollection instance
$collection = new \JetFire\Routing\RouteCollection();

// Define your routes
// ...

// Create an instance of Router
$router = new \JetFire\Routing\Router($collection)

// select your matcher
$matcher1 =  new \JetFire\Routing\Matcher\ArrayMatcher($router);
$matcher2 =  new \JetFire\Routing\Matcher\UriMatcher($router);

// set your matcher to the router
$router->setMatcher([$matcher1,$matcher2])

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

### Matcher

[](#matcher)

`JetFire\Routing` provide 2 type of matcher for your routes : `JetFire\Routing\Matcher\ArrayMatcher` and `JetFire\Routing\Matcher\UriMatcher`

#### Uri Matcher

[](#uri-matcher)

With Uri Matcher you don't have to define your routes. Depending on the uri it can check if a target exist for the current url. But you have to define your views directory path and controllers namespace to the collection :

```
$options = [
    'view_dir' => '_VIEW_DIR_PATH_',
    'ctrl_namespace' => '_CONTROLLERS_NAMESPACE_'
];
$collection = new \JetFire\Routing\RouteCollection(null,$options);
// or
$collection = new \JetFire\Routing\RouteCollection();
$collection->setOption($options);
// or
$collection = new \JetFire\Routing\RouteCollection();
$collection->addRoutes(null,$options)
```

For example if the uri is : `/home/index`

##### Resolver

[](#resolver)

Here are the list of Uri Matcher resolver :

```
$resolver = [
    'isControllerAndTemplate',
    'isController',
    'isTemplate'
];
```

##### Template resolver

[](#template-resolver)

Uri Matcher check if an `index.php` file exist in `/_VIEW_DIR_PATH_/Home` directory.

If you want to check for other extension (html,json,...) You can configure the router like this :

```
$router->setConfig([

	// Define your template extension like this
	'templateExtension' => ['.php','.html','.twig','.json','.xml'],

]);
```

##### Controller resolver

[](#controller-resolver)

With Controller resolver, Uri Matcher checks if a controller with name `HomeController` located in the namespace `_CONTROLLERS_NAMESPACE_` has the `index` method. You have to require your controller before matching or you can use your custom autoloader to load your controllers. Uri Matcher support also dynamic routes. For example if the uri is : `/home/user/peter/parker` then you must have a method `user` with two parameters like this :

```
class HomeController {
    public function user($firstName,$lastName){
        // $firstName = peter
        // $lastName = parker
    }
}
```

#### Array Matcher

[](#array-matcher)

With Array Matcher you have to add your routes like this :

```
$options = [
    'view_dir' => '_VIEW_DIR_PATH_',
    'ctrl_namespace' => '_CONTROLLERS_NAMESPACE_'
];

// addRoutes expect an array argument
$collection->addRoutes([
	'/home/index' => '_TARGET_'
],$options);

// or a file containing an array
$collection->addRoutes('path_to_array_file',$options);
```

We recommend that you define your routes in a separate file and pass the path to `addRoutes()` method.

```
// routes.php file
return [
	'/home/index' => '_TARGET_'
];
```

##### Resolver

[](#resolver-1)

Here are the list of Uri Matcher resolver :

```
$resolver = [
    'isControllerAndTemplate',
    'isClosureAndTemplate',
    'isClosure',
    'isController',
    'isTemplate'
];
```

You have 5 actions possible for Array Routing. We assume you are using a separate file for your routes.

##### Template resolver

[](#template-resolver-1)

```
return [

	// static route
	'/home/index' => 'Home/index.php',

	// dynamic route with arguments
	'/home/user-:id-:slug' => [
		'use' => 'Home/page.html',
		'arguments' => ['id' => '[0-9]+','slug' => '[a-z-]*'],
	],

];
```

##### Controller resolver

[](#controller-resolver-1)

```
return [

	// static route
	'/home/index' => 'HomeController@index',

	// dynamic route with arguments
	'/home/user-:id-:slug' => [
		'use' => 'HomeController@page',
		'arguments' => ['id' => '[0-9]+','slug' => '[a-z-]*'],
	],

];
```

##### Controller and Template resolver

[](#controller-and-template-resolver)

```
return [

	// controller and template resolver
	// call first the controller and render then the template
	// if the template is not found, the controller is returned
	'/home/log' => [
	    'use' => 'HomeController@log',
	    'template' => 'Home/log.php', //in your controller you can return an array of data that you can access in your template
	],

	// dynamic route with arguments
    '/home/user-:id-:slug' => [
        'use' => 'HomeController@page',
        'template' => 'Home/log.php',
        'arguments' => ['id' => '[0-9]+','slug' => '[a-z-]*'],
    ],

];
```

##### Controller group resolver

[](#controller-group-resolver)

```
return [

	// suppose we have the following methods in the AccountController :
	// public function create();
	// public function read($id);
	// public function update($id);
	// public function destroy($id);
	// if the uri is /account/create the router will call the associated method in the controller
	'/account/*' => [
	    'use' => 'AccountController@{method}',
	],

];
```

##### Closure resolver

[](#closure-resolver)

```
return [

	// static route
	'/home/index' => function(){
		return 'Hello world !';
	},

	// dynamic route with arguments
	'/home/user-:id-:slug' => [
		'use' => function($id,$slug){
			return 'Hello User '.$id.'-'.$slug;
		},
		'arguments' => ['id' => '[0-9]+','slug' => '[a-z-]*'],
	],

];
```

##### Closure and Template resolver

[](#closure-and-template-resolver)

```
return [

	// closure and template matching
    // call first the closure and render then the template
    '/home/log' => [
        'use' => function(){
            return ['name' => 'Peter'];
        }
        'template' => 'Home/log.php', // in log.php you can access the return data like this : $name ='Peter'
    ],

    '/home/user-:id-:slug' => [
        'use' => function($id,$slug){
            return ['id' => $id,'slug' => $slug];
        },
        'template' => 'Home/log.php',
        'arguments' => ['id' => '[0-9]+','slug' => '[a-z-]*'],
    ],

];
```

### Block Routes

[](#block-routes)

With `JetFire\Routing` you have the ability to create block routes to better organize your code. For example , if you have an administration for your website , you can create block only for this section and another block to the public part like this :

```
// Create RouteCollection instance
$collection = new \JetFire\Routing\RouteCollection();

// Block routes
$collection->addRoutes('admin_routes_path',['view_dir' => 'admin_view_path' , 'ctrl_namespace' => 'admin_controllers_namespace','prefix' => 'admin']);
$collection->addRoutes('public_routes_path',['view_dir' => 'public_view_path' , 'ctrl_namespace' => 'public_controllers_namespace']);

// Create an instance of Router
$router = new \JetFire\Routing\Router($collection)
// Select your matcher
$router->addRouter(new \JetFire\Routing\Matcher\ArrayMatcher($router));

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

### Router Configuration

[](#router-configuration)

Here are the list of router configuration that you can edit :

```
$router->setConfig([

	// You can add/remove extension for views
	// default extension for views
	'templateExtension'      => ['.html', '.php', '.json', '.xml'],

	// If you use template engine library, you can use this to render the view
	// See the 'Integration with other libraries' section for more details
	'templateCallback'       => [],

	// If you want to add a dependency injection container for your controllers constructor or method
	// for example if your controller 'HomeController' method 'log' method require a class like this : public function log(Request $request)
	// by default :
	'di'                => function($class){
	                            return new $class;
	                       },

	// See the Named Routes section for more details
	'generateRoutesPath' => false,
]);
```

### Collection Options

[](#collection-options)

Here are the list of options that you can edit for each collection routes :

```
$options = [
    // your view directory
    'view_dir' => 'view_directory',
    // your controllers namespace
    'ctrl_namespace' => 'controllers_namespace',
    // your routes prefix
    'prefix' => 'your_prefix'
];
```

### Named Routes

[](#named-routes)

You can specify a name for each route like this :

```
return [

	'/home/index' => [
		'use' => 'Home/index.html',
		'name' => 'home.index'
	],

	'/home/user-:id-:slug' => [
		'use' => 'HomeController@user',
		'name' => 'home.user',
		'arguments' => ['id' => '[0-9]+','slug' => '[a-z-]*'],
	],
];
```

And then to get the url of this route you can do like this :

```
// You have to enable generateRoutesPath to get routes url
$router->setConfig([
	'generateRoutesPath' => true,
	// Other configuration
	// ...
]);

// Reverse routing
$collection->getRoutePath('home.index'); // return http://your_domain/home/index
$collection->getRoutePath('home.user',[ 'id' => 1, 'slug' => 'toto']); // return http://your_domain/home/user-1-toto
```

Supported only in `JetFire\Routing\Matcher\ArrayMatcher`.

### REST Routing

[](#rest-routing)

You can specify the request method for each route like this :

```
return [

	'/api/users' => [
		'use' => [
		    'GET' => function($response){
		        $response->setHeaders(['Content-Type' => 'application/json']);
		        return ['name' => 'Peter'];
		    },
		    'POST' => function($response){
                $response->setHeaders(['Content-Type' => 'application/json']);
                $response->setStatusCode(201);
                return [];
            },
		],
		'name' => 'api.users',
		'method' => ['GET', 'POST']
	],

	'/api/users/:id' => [
		'use' => [
		    'GET' => function($response){
                $response->setHeaders(['Content-Type' => 'application/json']);
                return ['name' => 'Peter'];
            },
            'PUT' => function($response){
                $response->setHeaders(['Content-Type' => 'application/json']);
                return [];
            },
		],
		'name' => 'api.user',
		'arguments' => ['id' => '[0-9]+'],
		'method' => ['GET','PUT']
	],
];
```

### Prefix

[](#prefix)

You can set a prefix for each routes collection like this :

```
$collection->addRoutes('routes_file_1',['prefix' => 'prefix_1']); // all routes in routes_file_1 begin with prefix_1/
$collection->addRoutes('routes_file_2',['prefix' => 'prefix_2']); // all routes in routes_file_2 begin with prefix_2/
```

Or :

```
$collection->addRoutes('routes_file_1');
$collection->addRoutes('routes_file_2');
$collection->setPrefix(['prefix_1','prefix_2']);
```

### Middleware

[](#middleware)

Middlewares are called before and after a route match the current uri. You have to create a middleware config file like this :

```
// Your middleware file
return [

	// global middleware are called every time
    'global_middleware' => [
    	// Here you define your middleware class to be called
        'app\Middleware\Global',
    ],

	// block middleware are called when the current route block match one of the following block
    'block_middleware' => [
    	// You define here for each block the middleware class to be called
        '/app/Blocks/PublicBlock/' => 'app\Middleware\Public',
        '/app/Blocks/AdminBlock/' => 'app\Middleware\Admin',
        '/app/Blocks/UserBlock/' => 'app\Middleware\User',
    ],

	// class middleware are called when the controller router match one of the following controller
    'class_middleware' => [
    	// You define here for each controller the middleware class to be called
        '/app/Blocks/PublicBlock/Controllers/HomeController' => 'app\Middleware\Home',
    ],

	// route middleware are called when the current route match one of the following middleware name
    'route_middleware' => [
    	// You define here a name to the middleware and assign the class to be called
    	// You have to specify this name to the route like this : `'middleware' => 'home'`
        'home' => 'app\Middleware\App'
    ],

];
```

Then you have to instantiate the middleware class `Middleware` like this :

```
$middleware = new Middleware($router);
$middleware->setCallbackAction('before', 'your_before_middleware_file');
$middleware->setCallbackAction('between', 'your_between_middleware_file');
$middleware->setCallbackAction('after', 'your_after_middleware_file');

$router->addMiddleware($middleware);
```

Let see how to create your Middleware Class. For example we take the Global middleware :

```
namespace app\Middleware;

class Global{

	// Middleware class must implements handle method
	// object passed in argument will be inject automatically
	public function handle(){
		// here you put your code
		// ...
	}
}
```

See the API section to learn how to handle your $route in middleware class.

### Custom Matcher and Dispatcher

[](#custom-matcher-and-dispatcher)

If the default matcher and dispatcher doesn't match your expectation, you can write your own matcher and dispatcher like this :

```
class MyCustomMatcher implements MatcherInterface{

    public function __construct(Router $router);

    // in this method you can check if the current uri match your expectation
    // return true or false
    // if it match you have to set your route target with an array of params and the dispatcher class name to be called
    // $this->setTarget(['dispatcher' => '\My\Custom\Dispatcher\Class\Name', 'other_params' => 'values']);
    public function match();

    // set your route target $this->router->route->setTarget($target);
    public function setTarget($target = []);

    // set your resolver
    public function setResolver($resolver = []);

    // you can add multiple resolver method in the same matcher
    public function addResolver($resolver);

    // to retrieve your resolver
    public function getResolver();

    // dispatcher yo be called
    public function setDispatcher($dispatcher = []);

    public function addDispatcher($dispatcher);
}

class MyCustomDispatcher implements DispatcherInterface{

    public function __construct(Router $router);

    // your target to call
    // you can get your route target information with $this->route->getTarget()
    public function call();
}

$router->addMatcher('MyCustomMatcher');
```

You can also override the default matcher like this :

```
class MyCustomMatcher extends ArrayMatcher implements MatcherInterface{

    public function __construct(Router $router){
        parent::__construct($router);
        // your custom match method
        $this->addResolver('customResolver');
    }

    public function customResolver(){
        // your code here
        // ...
        // then you set the route target with the dispatcher
    }
}

class MyCustomDispatcher implements DispatcherInterface{

    public function __construct(Router $router);

    // your target to call
    // you can get your route target information with $this->route->getTarget()
    public function call();
}
```

### Integration with other libraries

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

If you want to integrate other template engine libraries like twig, smarty ... you have to set the 'templateCallback' in router.

```
// Twig template engine
require_once '/path/to/lib/Twig/Autoloader.php';
Twig_Autoloader::register();

// Other template engine
$tpl = new \Acme\Template\Template();

$router->setConfig([
	'templateCallback' => [

		// if the router find a template with twig enxtension then it will call the twig template engine
		'twig' => function($route){
			$loader = new Twig_Loader_Filesystem($route->getTarget('block'));
			$twig = new Twig_Environment($loader, []);
			$template = $twig->loadTemplate($route->getTarget('template'));
			echo $template->render($route->getData());
		},

		// for other template engine
		'tpl' => function($route) use ($tpl){
			$tpl->load($route->getTarget('template'));
			$tpl->setData($route->getData());
			$tpl->display();
		}
	],

	// Other configuration
	// ...
]);
```

### Subdomain

[](#subdomain)

```
return [
    '{subdomain}.{host}/home' => [
         'use' => 'AdminController@index',
         'name' => 'admin.home.index',
         'subdomain' => 'admin' // could be a regex for multiple subdomain
    ]
];
```

Or if you want to add a subdomain for a bloc, you have to add this line in your route collection options :

```
$options = [
    // ...
    'subdomain' => 'your_subdomain'
];
```

### API

[](#api)

Below is a list of the public methods and variables in the common classes you will most likely use.

```
// JetFire\Routing\RouteCollection
$collection->
	routesByName								// routes url by their name
	countRoutes									// count routes block
	addRoutes($collection,$options = [])		// set your routes
	getRoutes($key = null)						// return all routes
	getRoutePath($name,$params = []) 			// return the url of route
	setPrefix($prefix)							// $prefix can be a string (applied for every collection)
												// or an array (for each collection you can specify a prefix)
    setOption($options = [])                    // set your routes option
	generateRoutesPath() 						// generate routes url by their name

// JetFire\Routing\Router
$router->
	response							        // JetFire\Routing\ResponseInterface instance
	route										// JetFire\Routing\Route instance
	collection									// JetFire\Routing\RouteCollection instance
	middlewareCollection					    // middleware collection
	matcher									    // list of matcher
	dispatcher									// the dispatcher instance
	setConfig($config) 							// router configuration
	getConfig() 								// get router configuration
	run() 										// run the router with the request url

// JetFire\Routing\Route
$route->
	set($args = []) 							// set your route array parameters
	getUrl() 									// return the route url
	setUrl($url) 								// set the route url
	getName()			 						// return the route name
	setName($name) 								// set the route name
	getCallback()  								// return the route callback (template,controller or anonymous function)
	setCallback($callback) 						// set the route callback
	getMethod() 								// return the route method (GET,POST,PUT,DELETE)
	getDetail() 								// return the route detail
	setDetail($detail) 							// set the route detail
	addDetail($key,$value)						// add a detail for the route
	getTarget($key = null) 						// return the route target (dispatcher,template or controller|action or function)
	setTarget($target = [])  					// set the route target
	hasTarget($key = null)						// check if the route has the following target
	getData() 								    // return data for the route
	__call($name,$arguments)  					// magic call to get or set route detail
```

### License

[](#license)

The JetFire Routing is released under the MIT public license : .

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity20

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity62

Established project with proven stability

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

Total

4

Last Release

3635d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/7b1f2a3db41601a0dd4b4bd774cf48673b6cd3c2208062b4a6f1b7697a817c3f?d=identicon)[jetfirephp](/maintainers/jetfirephp)

---

Top Contributors

[![mewgan](https://avatars.githubusercontent.com/u/17544034?v=4)](https://github.com/mewgan "mewgan (11 commits)")

---

Tags

dispatcherRounting

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[league/route

Fast routing and dispatch component including PSR-15 middleware, built on top of FastRoute.

6633.1M115](/packages/league-route)[indatus/dispatcher

Schedule your artisan commands within your application's source code

1.1k855.3k2](/packages/indatus-dispatcher)[contributte/event-dispatcher

Best event dispatcher / event manager / event emitter for Nette Framework

292.4M19](/packages/contributte-event-dispatcher)[jmikola/wildcard-event-dispatcher

Event dispatcher with support for wildcard patterns inspired by AMQP topic exchanges.

32320.9k2](/packages/jmikola-wildcard-event-dispatcher)[cakephp/event

CakePHP event dispatcher library that helps implementing the observer pattern

23319.7k13](/packages/cakephp-event)[aura/dispatcher

Creates objects from a factory and invokes methods using named parameters; also provides a trait for invoking closures and object methods with named parameters.

3695.0k3](/packages/aura-dispatcher)

PHPackages © 2026

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