PHPackages                             iassasin/easyroute - 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. iassasin/easyroute

ActiveLibrary[Framework](/categories/framework)

iassasin/easyroute
==================

Very lightweight and simple router for PHP

v0.10.0(7y ago)052[2 issues](https://github.com/iassasin/easyroute/issues)MITPHPPHP &gt;=7.0

Since Aug 19Pushed 7y agoCompare

[ Source](https://github.com/iassasin/easyroute)[ Packagist](https://packagist.org/packages/iassasin/easyroute)[ Docs](https://github.com/iassasin/easyroute)[ RSS](/packages/iassasin-easyroute/feed)WikiDiscussions master Synced 2w ago

READMEChangelogDependencies (3)Versions (12)Used By (0)

Easyroute
=========

[](#easyroute)

[![PHP Version](https://camo.githubusercontent.com/5c3072425e67297c8ef63d17acd2c86a0d2ef324f19249f2280bd7de902f63a2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344253230372e302d3838393242462e737667)](https://php.net/)[![Build Status](https://camo.githubusercontent.com/aaa92bbe8f353d8f7891c4c283835996f0b0d26abd7f0cc1ea16c64e294d9fb4/68747470733a2f2f7472617669732d63692e6f72672f696173736173696e2f65617379726f7574652e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/iassasin/easyroute)[![Coverage Status](https://camo.githubusercontent.com/73646bf4d35c8fa007a7333bc064fd70e22021933f6a3c0ddb6869fd87706e99/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f696173736173696e2f65617379726f7574652f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/iassasin/easyroute?branch=master)

Simple router do not require a lot of setups, install in few minutes and just works.

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

[](#installation)

To start using router complete 4 simple steps:

1. Install `easyroute` via composer:

```
composer require iassasin/easyroute

```

2. Setup yours routes in root directory of project. For example in file `routes.php`:

```
require_once 'vendor/autoload.php';
use Iassasin\Easyroute\Router;
use Iassasin\Easyroute\Route;

$router = new Router();
$router->setControllersPath($_SERVER['DOCUMENT_ROOT'].'/controllers/');
$router->addRoutes([
	new Route('/(:controller:(/:action:(/:arg)?)?)?', ['controller' => 'home', 'action' => 'index', 'arg' => null]),
]);
$router->processRoute();
```

3. Tell web server redirect all requests (except static `assets/`) to router via `.htaccess`:

```
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/assets/
RewriteRule ^(.*)$ routes.php [B,QSA,L]

```

4. Create first controller in `controllers/home.php`:

```
class ControllerHome {
	public function index($arg){
		return 'Home page! '.($arg !== null ? 'Argument: '.$arg : 'Argument not set').'';
		// or use "return new Response('...')" which is more flexible
	}
}
```

That's it!

Note that file name must match `:controller` name from URL template and controller class name must match `:controller` name with prefix `Controller`. In example above route `/home/index` matches file `controllers/home.php` and class `ControllerHome`.

Useful features
---------------

[](#useful-features)

### Route with parameters

[](#route-with-parameters)

Route is a regex string with simpler syntax for naming route arguments. For example:

- `/:controller/:action/:arg` (all parameters are required)
- `/(foo|bar)-:arg/gotcha` (regex and partial parameter matching. Valid are `/foo-123/gotcha`, `/bar-qwerty/gotcha`, but not `/qwerty/gotcha`)
- `/:arg?` (parameter `arg` can be ommited, but not `/`. Valid are `/`, `/param`, but not `/sub/param`)
- `/(:controller:(/:action:(/:arg)?)?)?` (all parameters not required. Valid are `/`, `/home`, `/home/index/val`, but not `/home/`, `/home/index/`)

Parameter name must match regex `[a-zA-Z_0-9]+`.
By default `:parameter` match regex `[^\/]+`, but you can use your own filter:

```
new Route('/:arg(\d+)?', // arg not required and can contains only numerics
	['controller' => 'home', 'action' => 'index', 'arg' => null], // default values
)
```

If you need to use `(` to match group, but not to filter parameter, use trailing `:` in parameter name: `/:controller:(postfix1|postfix2)` will match `/homepostfix1` with `controller = 'home'`.

### Built-in simple dependency injection container

[](#built-in-simple-dependency-injection-container)

You can use built-in dependency injection container to split app code into services (which will be loaded via autoload) and simply use it in controller's actions:

```
class ControllerHome {
	public function index($arg, Request $request, DatabaseService $db){
		// ...
	}
}
```

Services constructors can use dependency injection too and require another services via same syntax.

Class `SampleContainer` impletents `Psr\Container\ContainerInterface`.

```
use Iassasin\Easyroute\Router;

$router = new Router();
/** @var SimpleContainer $container */
$container = $router->getContainer(); // get default container

// Instantiate and add services by hand
$container->setService(Database::class, new Database('login', 'password'));
// Disable automatic instantiation for services
$container->setAutowireEnabled(false);
```

Also you can use another dependency injection container:

```
use Iassasin\Easyroute\Router;
use Iassasin\Easyroute\Http\Request;

$router = new Router();
$request = Request::createFromGlobals();

// some implementation of ContainerInterface
$container = new MyContainer();
// Router don't know how to register Request class in your container implementation
// You should to do it by self if you want to use Request class in controllers
// See next section for details of Request class
$container->register(Request::class, $request);

$router->setContainer($container);
```

### Request class

[](#request-class)

Using dependency injection container you have access to `Request` service that provides access to request parameters.

`Request` has fields listed below:

- `query` - `$_GET` array
- `request` - `$_POST` array
- `attributes` - assoc array with any data, which you can set at `Request` instance creation
- `cookies` - `$_COOKIE` array
- `files` - `$_FILES` array
- `server` - `$_SERVER` array

Each field is instance of `Parameters` class and has methods:

- `get(string $name)` - get parameter by it's name
- `has(string $name)` - does parameter with `$name` exists
- `all()` - get all parameters in array

`Request` provide some useful methods:

- `getContent()` - get whole http post content as string
- `getClientIP()` - returns `$this->server->get('REMOTE_ADDR')`
- `getScriptName()` - returns `$this->server->get('SCRIPT_NAME')`
- `getScheme()` - returns `$this->server->get('REQUEST_SCHEME')`
- `getHost()` - returns `$this->server->get('SERVER_NAME')`
- `getUri()` - returns `$this->server->get('REQUEST_URI')`
- `getMethod()` - returns `$this->server->get('REQUEST_METHOD')`
- `getProtocol()` - returns `$this->server->get('SERVER_PROTOCOL')`

### Response class

[](#response-class)

`Response` class used to return data to client. Return `Response` instances from controller's actions instead of manual data send using echo or etc.

#### Built-in response classes

[](#built-in-response-classes)

There is 3 built-in response classes:

- `Response` - base class for all responses, has methods:
    - `__construct(string $content, int $statusCode = 200, array $headers = [])`
    - `getStatusCode()`, `setStatusCode(int $code)` - get/set http status code
    - `getContent()`, `setContent(string $content)` - get/set http response content
    - `getHeaders()`, `setHeaders(array $headers)` - get/set http headers
    - `setHeader(string $name, string $value)` - set single header
    - `send()` - send response to client, called from handlers
- `Response404` - extends `Request` for default http 404 error with:
    - `__construct(string $url, array $headers = [])`
    - `getUrl()` - get URL caused 404 error
- `Response500` - extends `Request` for default http 500 error. Generated if any exception thrown during route processing.
    - `__construct(\Throwable $exception = null, array $headers = [])`
    - `getException()` - get exception thrown during route processing
- `ResponseJson` - extends `Request` for sending json responses, also set correct http `Content-Type` header.
    - `__construct(object|array $data, int $statusCode = 200, array $headers = [])`
    - `getData()`, `setData(object|array $data)` - set source data to send to client
    - Note that `setContent` can't be used and throws `LogicException`

#### Custom handlers for response classes

[](#custom-handlers-for-response-classes)

Set custom handlers for `Response` classes:

```
use Iassasin\Easyroute\Http\Responses\Response404;

$router->setResponseHandler(Response404::class, function(Response404 $resp){
	$resp->setContent('Custom 404 Not Found The requested url "'.htmlspecialchars($resp->getUrl()).'" not found!');
	$resp->send();
	return true; // do not call other handlers
});
```

And custom handlers for any http status code:

```
use Iassasin\Easyroute\Http\Response;

$router->setStatusHandler(302, function(Response $resp){
	$resp->setContent('You have redirected');
	$resp->send();
	return true; // do not call other handlers
});
```

> Note 1: you can use both handlers set, but response handlers will be called first (and can stop calling status handlers).
>
> Note 2: you can set handler for parent response class to match all childs, child handlers will be always called first: from most child to first parent. So, you can match **all** responses setting handler for `Response::class`.

### Subdirectories for controllers

[](#subdirectories-for-controllers)

Separate zones with subdirectories:

```
(new Route('/admin/:controller/:action?', ['action' => 'index']))
	->setControllersSubpath('zones/admin')
	// '/admin/home/index' will match 'controllers/zones/admin/home.php'
	// and class 'ControllerHome'
```

### Filtering access

[](#filtering-access)

Use `RouteFilter` to prevent access to some routes:

```
use Iassasin\Easyroute\RouteFilter;

class RouteFilterAdmin extends RouteFilter {
	public function preRoute($path, $controller, $action, $args){
		if (!isCurrentUserAdmin()){
			(new Response('Access denied!', 403))->send();
			return Router::COMPLETED; // Do not call controller's action
		}

		return Router::CONTINUE; // Call controller's action
	}
}
//...
(new Route('/admin/:controller/:action?', ['action' => 'index']))
	->setFilter(new RouteFilterAdmin())
```

### Custom controller class name prefix

[](#custom-controller-class-name-prefix)

Set custom controller class name prefix (default - `Controller`):

```
$router->setControllerClassPrefix('TheController');
```

###  Health Score

25

—

LowBetter than 35% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity55

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

Recently: every ~71 days

Total

11

Last Release

2790d ago

PHP version history (2 changes)v0.2.0PHP &gt;=5.6

v0.7.0PHP &gt;=7.0

### Community

Maintainers

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

---

Top Contributors

[![iassasin](https://avatars.githubusercontent.com/u/20709774?v=4)](https://github.com/iassasin "iassasin (45 commits)")

---

Tags

composercontrollerphpphp56php7routerroutermvccontrollerroute

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/iassasin-easyroute/health.svg)

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

###  Alternatives

[symfony/symfony

The Symfony PHP framework

31.4k86.9M2.2k](/packages/symfony-symfony)[cakephp/cakephp

The CakePHP framework

8.8k19.1M1.7k](/packages/cakephp-cakephp)[tempest/framework

The PHP framework that gets out of your way.

2.2k31.1k12](/packages/tempest-framework)

PHPackages © 2026

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