PHPackages                             dcp/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. [HTTP &amp; Networking](/categories/http)
4. /
5. dcp/router

ActiveLibrary[HTTP &amp; Networking](/categories/http)

dcp/router
==========

Provides an extensible, event-oriented, MVC and REST router

v1.0.0(12y ago)144[1 issues](https://github.com/estelsmith/dcp-router/issues)MITPHP

Since Jan 11Pushed 10y ago1 watchersCompare

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

READMEChangelog (1)Dependencies (3)Versions (3)Used By (0)

*WARNING: UNMAINTAINED!*
========================

[](#warning-unmaintained)

\#DCP-Router DCP-Router provides an extensible, event-oriented, MVC and REST router.

Design goals for the project are always to be concise, simple, extensible, and testable.

[![Build Status](https://camo.githubusercontent.com/cf7cd86207b1a5dc391aca80cb0ea6c28adc67fe6c243b3c7a57e9ff2b3284a2/68747470733a2f2f7472617669732d63692e6f72672f657374656c736d6974682f6463702d726f757465722e706e673f6272616e63683d6d6173746572)](https://travis-ci.org/estelsmith/dcp-router)[![Coverage Status](https://camo.githubusercontent.com/8b652b79dd235c870060fabfdcf4a189b54642ea49fe40cd882bb017caa8528e/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f657374656c736d6974682f6463702d726f757465722f62616467652e706e67)](https://coveralls.io/r/estelsmith/dcp-router)

Getting Started
---------------

[](#getting-started)

The easiest, and recommended, way of installing the package is [through composer](http://getcomposer.org/).

Just create a composer.json file in your project, and add the following lines:

```
{
    "require": {
        "dcp/router": "1.0.*"
    }
}
```

Then, run the composer command to install DCP-Router:

```
$ composer install

```

Alternatively, you can clone the repository and install the package manually.

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

[](#basic-usage)

### Creating MVC Or REST Routers

[](#creating-mvc-or-rest-routers)

The first thing you need to do is instantiate your router. You can choose between an MVC or REST router.

```
use DCP\Router;

$mvcRouter = new Router\MvcRouter();

$restRouter = new Router\RestRouter();
```

### Route Dispatching

[](#route-dispatching)

Once you have created the router, you can begin dispatching routes immediately without any other configuration.

By default, the router will look for controller classes in the root namespace. This is configurable, and is shown in other areas of this README.

For example, if you choose the MVC router to dispatch routes:

```
use DCP\Router\MvcRouter;

class TestController
{
    public function indexAction($arg = null)
    {
        echo __METHOD__ . ', ' . $arg;
    }
}

class HomeController
{
    public function testAction()
    {
        echo __METHOD__;
    }
}

$router = new MvcRouter();

$router->dispatch('/test/index/hello');
// This will output "TestController::indexAction, hello"

$router->dispatch('/home/test');
// This will output "HomeController::testAction"
```

Alternatively, if you choose the REST router to dispatch routes:

```
use DCP\Router\RestRouter;

class UsersController
{
    public function get()
    {
        echo __METHOD__;
    }

    public function post($arg = null)
    {
        echo __METHOD__ . ', ' . $arg;
    }
}

$router = new RestRouter();

$router->dispatch('/users/hello', 'post');
// This will output "UsersController::post, hello"

$router->dispatch('/users', 'get');
// This will output "UsersController::get"
```

### Default Routes

[](#default-routes)

When no URL, or a partial URL, is presented to the router, it will assume a default route in order to avoid throwing a NotFound exception.

In the case of the MVC Router, when no route is presented, it will assume an index controller with an index action. If a controller is specified, but not an action, it will assume the index action is to be called.

```
use DCP\Router\MvcRouter;

class IndexController
{
    public function indexAction()
    {
        echo __METHOD__;
    }
}

class HomeController
{
    public function indexAction()
    {
        echo __METHOD__;
    }
}

$router = new MvcRouter();

$router->dispatch('/');
// This will output "IndexController::indexAction"

$router->dispatch('/home');
// This will output "HomeController::indexAction"
```

In the case of the REST router, when no route is presented, it will assume an index controller with a GET method. If a controller is specified, but not an HTTP method, it will assume the GET method is to be called.

```
use DCP\Router\RestRouter;

class IndexController
{
    public function get()
    {
        echo __METHOD__;
    }
}

class HomeController
{
    public function get()
    {
        echo __METHOD__;
    }

    public function post()
    {
        echo __METHOD__;
    }
}

$router = new RestRouter();

$router->dispatch('/');
// This will output "IndexController::get"

$router->dispatch('/home');
// This will output "HomeController::get"

$router->dispatch('/home', 'post');
// This will output "HomeController::post"
```

### Not Found Errors

[](#not-found-errors)

When the router is not able to find a specified resource, it will throw a NotFoundException, allowing you to display a 404 page if desired.

```
use DCP\Router\MvcRouter;

$router = new MvcRouter(); // RestRouter can be used here, too.

try {
    $router->dispatch('/home');
} catch (NotFoundException $e) {
    echo 'Could not find /home!!';
}
```

### Controller Namespace Prefixes

[](#controller-namespace-prefixes)

When your application becomes complex enough to require structuring with namespaces, you can begin setting namespace prefixes for the router use. The router will look for controllers in whatever namespace you specify.

```
// App/Controller/TestController.php
namespace App\Controller;

class TestController
{
    public function helloAction()
    {
        echo 'Hello, world!';
    }
}
```

```
// index.php
use DCP\Router\MvcRouter;

$router = new MvcRouter();
$router->setControllerPrefix('App\Controller');

$router->dispatch('/test/hello');
// This will output "Hello, world!"
```

### Router Hierarchy

[](#router-hierarchy)

DCP-Router gives you the ability to create separate site areas with their own URL prefix, such as an administrative site section living under `/admin`.

In order to facilitate this type of functionality, the project relies on hierarchical routing, where the router will pass the URL off to other router instances when a known prefix is seen.

As an example, we will create a controller that should only be reachable by a `/admin` URL prefix.

```
// App/Admin/Controller/TestController.php
namespace App\Admin\Controller;

class TestController
{
    public function helloAction()
    {
        echo 'Hello, world!';
    }
}
```

Then, we will create an `AdminRouter` class to facilitate routing to the `App\Admin\Controller` namespace of the site.

```
// App/Admin/AdminRouter.php
namespace App\Admin;

use DCP\Router\MvcRouter;

class AdminRouter extends MvcRouter
{
    public function __construct()
    {
        parent::__construct();
        $this->setControllerPrefix('App\Admin\Controller');
    }
}
```

Finally, we instantiate a router, and tell it that anything under the `/admin` URL prefix should be handled by `AdminRouter`.

```
// index.php

use DCP\Router\MvcRouter;

$router = new MvcRouter();
$router->setComponents([
    'admin' => 'App\Admin\AdminRouter'
]);

$router->dispatch('/admin/test/hello');
// This will output "Hello, world!"
```

When the router is told to route to `/admin/test/hello`, it will see that the first piece of the URL is `admin`. Since a component was registered with the `admin` key, the router will dispatch the `/test/hello` portion of the route to `AdminRouter`, which will then end up calling `TestController#helloAction()`.

Detailed Usage
--------------

[](#detailed-usage)

### Event System

[](#event-system)

The core of DCP-Router utilizes [Evenement](https://github.com/igorw/evenement) and has events for every step of the routing process. This allows you to tie in to any point of the process and execute custom logic, if needed.

There are a total of twelve events, six that are called when a controller is dispatched, and six that are called when a secondary router is dispatched. Events are called in the order listed for their respective areas.

Controller events:

- `ControllerEvents::CREATING` is emitted when the router is resolving the fully qualified classname of the controller that is being dispatched to.
    - This event can be used for custom controller resolving logic.
- `ControllerEvents::CREATE` is emitted when the router instantiates the controller.
    - This event can be used for custom class creation logic.
- `ControllerEvents::CREATED` is emitted after the router has instantiated the controller.
- `ControllerEvents::DISPATCHING` is emitted when the router is resolving the method name to call on the controller.
    - This event can be used for custom controller method resolving logic.
- `ControllerEvents::DISPATCH` is emitted when the router called the resolved controller method.
    - This event can be used for custom controller action dispatch logic.
- `ControllerEvents::DISPATCHED` is emitted after the router has called the resolved controller method.

Component events:

- `ComponentEvents::CREATING` is emitted when the router is resolving the fully qualified classname of the component router to dispatch to. By default, it is the class name specified in the `*Router#setComponents()` call.
- `ComponentEvents::CREATE` is emitted when the router instantiates the component router.
    - This event can be used for custom class creation logic.
- `ComponentEvents::CREATED` is emitted after the router instantiates the component router.
- `ComponentEvents::DISPATCHING` is emitted when the router is preparing to pass control over to the component router.
- `ComponentEvents::DISPATCH` is emitted when the router hands control over to the component router.
    - This event can be used to provide custom component dispatch logic.
- `ComponentEvents::DISPATCHED` is emitted after the router has handed control over to the component router, and the component router has finished.

To tie into an event, you can simply attach a listener for the event. It will be called when the router enters the specific stage of routing.

```
use DCP\Router\MvcRouter;
use DCP\Router\ControllerEvents;
use DCP\Router\Event\CreatingEvent;

class TestControllerHi
{
    public function indexAction()
    {
        echo 'Hello!!'
    }
}

$router = new MvcRouter();
$router->on(ControllerEvents::CREATING, function (CreatingEvent $event) {
    $event->setClass($event->getClass() . 'Hi');
});

$router->dispatch('/test');
// This will output "Hello!!"
```

### Coupling With Dependency Injection Containers

[](#coupling-with-dependency-injection-containers)

One important aspect of the event system is that it allows for easy integration into various dependency injection containers.

The `ControllerEvents::CREATE` and `ComponentEvents::CREATE` events are specifically for instantiating a class, so they can be overridden to pull instances out of a DI container.

```
use DCP\Router\MvcRouter;
use DCP\Router\ControllerEvents;
use DCP\Router\ComponentEvents;
use DCP\Di\Container;
use DCP\Di\ContainerAwareInterface;

class DiMvcRouter extends MvcRouter implements ContainerAwareInterface
{
    protected $container;

    public function setContainer(Container $container)
    {
        $this->container = $container;
    }

    public function __construct()
    {
        parent::__construct();

        $createCallback = function (CreateEvent $event) {
            $container = $this->container;
            $class = $event->getClass();
            $event->setInstance($container->get($class));
        };

        $this->removeAllListeners(ControllerEvents::CREATE);
        $this->on(ControllerEvents::CREATE, $createCallback);

        $this->removeAllListeners(ComponentEvents::CREATE);
        $this->on(ComponentEvents::CREATE, $createCallback);
    }
}
```

Contributing
------------

[](#contributing)

If you would like to contribute to DCP-Router, you can do so in one of two ways:

- Submit issues for bugs you find, or functionality that would improve the project.
- Fork the repository, and submit a pull request.

Testing
-------

[](#testing)

DCP-Router utilizes PHPUnit 3.7.x for automated testing.

All changes to the codebase are accompanied by unit tests.

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance0

Infrequent updates — may be unmaintained

Popularity9

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 96% 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

Unknown

Total

1

Last Release

4506d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/d749ac0a0f0c2e479074aab7d3027392814ec71b882ab362c90637db2e62e82e?d=identicon)[estel.smith](/maintainers/estel.smith)

---

Top Contributors

[![estelsmith](https://avatars.githubusercontent.com/u/363670?v=4)](https://github.com/estelsmith "estelsmith (24 commits)")[![esmith-pltw](https://avatars.githubusercontent.com/u/15933733?v=4)](https://github.com/esmith-pltw "esmith-pltw (1 commits)")

---

Tags

restroutingmvc

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[aplus/app

Aplus Framework App Project

5951.6M1](/packages/aplus-app)[aplus/mvc

Aplus Framework MVC Library

2601.6M3](/packages/aplus-mvc)[handcraftedinthealps/rest-routing-bundle

This bundle provides automatic route registration for the Controllers

582.0M2](/packages/handcraftedinthealps-rest-routing-bundle)[contributte/api-router

RESTful Router for your Apis in Nette Framework - created either directly or via attributes

20802.8k3](/packages/contributte-api-router)[elementaryframework/water-pipe

URL routing framework and requests/responses handler for PHP

254.6k4](/packages/elementaryframework-water-pipe)

PHPackages © 2026

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