PHPackages                             rubberydub/snout - 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. rubberydub/snout

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

rubberydub/snout
================

Snout is a PHP request router

v1.0.0-alpha(8y ago)20MITPHPPHP &gt;=7.1

Since Nov 19Pushed 8y ago1 watchersCompare

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

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

Snout PHP request router
========================

[](#snout-php-request-router)

[![Build Status](https://camo.githubusercontent.com/e5b1c051451499d4a475e5f7ab4683f4151a0576441bce4db64bf9f08f55520d/68747470733a2f2f7472617669732d63692e6f72672f727562626572796475622f736e6f75742e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/rubberydub/snout)[![Coverage Status](https://camo.githubusercontent.com/28b6cca862d453aaf73205686bde964c53820016b2f3982ed4def6515b41a5f2/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f727562626572796475622f736e6f75742f62616467652e737667)](https://coveralls.io/github/rubberydub/snout)[![Latest Stable Version](https://camo.githubusercontent.com/7b7146b2c5e9a5b4e2292351ea6f8465f1e09c07e2baecbd0204ab16267307dc/68747470733a2f2f706f7365722e707567782e6f72672f727562626572796475622f736e6f7574)](https://packagist.org/packages/rubberydub/snout)

Snout is a PHP request router.

Contents
--------

[](#contents)

- [Features](#features)
- [Installing](#installing)
- [Quick Example](#quick-example)
- [Controllers](#controllers)
- [Routes](#routes)
- [Embedded Parameters](#embedded-parameters)
- [Sub-Routing](#sub-routing)
- [License](#license)

Features
--------

[](#features)

- Flexible controller types.
- Extraction and type casting of embedded parameters.
- Custom embedded parameter types.
- Combinable route sets allowing sub-routing.

Installing
----------

[](#installing)

Use [Composer](http://getcomposer.org).

```
composer require rubberydub/snout
```

Quick Example
-------------

[](#quick-example)

```
use Snout\Router;
use Snout\Route;
use Snout\Request;
use Snout\Parameter;

$router = new Router();
$router->push(new Route([
    'name'       => 'user',
    'path'       => '/groupId/{group_id: integer}/name/{name: string}',
    'controller' => [
        'get' => function($parameters) {
            echo 'User name:     ' . $parameters->get('name') . PHP_EOL
              .  'User group id: ' . $parameters->get('group_id') . PHP_EOL;
        }
    ]
]));

$route = $router->run(new Request('/groupId/3/name/John, 'get'));
// User name:     John
// User group id: 3
```

Controllers
-----------

[](#controllers)

Controllers do not need to be a function. The router does not need to run the controllers. It can simply provide the controllers for the matching route and the embedded parameters for you do use as you please.

```
use Snout\Router;
use Snout\Route;
use Snout\Request;
use Snout\Parameter;
use My\Container;
use My\Controller;

$router = new Router();
$my_container = new Container();
$my_controller = new Controller();

$router->push(new Route([
    'name'       => 'page',
    'path'       => '/pages/{page_id: integer}',
    'controller' => $my_controller
]));

$request = new Request('/page/3', 'get');
$route = $router->match($request);

$controller = $route->getController();
$parameters = $route->getParameters();

$controller->run(
    $my_container,
    $parameters,
    $request->getMethod()
);
```

Routes
------

[](#routes)

Specifiy routes by creating `\Snout\Route` objects. Routes accept an array or `Ds\Map` of options:

NameTypeDescriptionname`string`A name for the routepath`string`The path of the routecontroller`mixed`Map from HTTP method to controller, or a single controllerparameters`array|\Ds\Map`Optional custom embedded parameterssub\_router`\Ds\Router`An optional sub-routerExample:

```
$tokens = new Route([
    'name'        => 'tokens',
    'path'        => '/user/{user_id: integer}/tokens',
    'controllers' => ['get' => $get_token_controller]
])
```

Embedded Parameters
-------------------

[](#embedded-parameters)

The router will match the path exactly, except for embedded parameters, which it will extract.

Embedded parameters are specified in a route's path like so:

```
{NAME: TYPE}

```

For example:

```
/collection/{id: integer}

```

By default there are four embedded parameter types: `string`, `boolean`, `integer` and `float`. Extracted parameters are casted to the appropriate type.

#### Optional/Nullable Parameters

[](#optionalnullable-parameters)

Embedded parameters may be optional or nullable by prefixing the type with `?` like so:

```
/optional/{id: ?string}

```

If the parameter is not present or is `'null'` then the extracted parameter will have value `null`.

#### Custom Parameter Types

[](#custom-parameter-types)

Custom parameter types are available. Provide them in a routes options like so:

```
use Snout\Route;

$route = new Route([
    'name'        => 'region',
    'path'        => '/region/{name: label}',
    'controllers' => ['get' => $get_region_controller]
    'parameters' => [
        'label' => [
            'tokens' => [
                'DIGIT', // All digits
                'ALPHA', // All letters
                'UNDERSCORE',
                'HYPHEN
            ],
            'cast' => 'string'
        ]
    ]
]);
```

Available Tokens:

NameMatches`DIGIT`All digits`ALPHA`All letters`UNDERSCORE``_``HYPHEN``-``PERIOD``.``COLON``:``OPEN_BRACE``{``CLOSE_BRACE``}``OPEN_BRACKET``[``CLOSE_BRACKET``]``BACK_SLASH``\`Sub-Routing
-----------

[](#sub-routing)

Routers can be combined to allow sub-routing at a particalar part of the path. Parent router's controllers can be extracted and executed before the sub routing.

```
use Snout\Router;
use Snout\Route;
use Snout\Request;
use Snout\Parameter;

$users_router = new Router();
$users_router->push(new Route([
    'name'        => 'user_by_id',
    'path'        => '/{id: integer}',
    'controllers' => [
        'get' => function ($parameters) {
            echo 'User id: ' . $parameters->get('id') . PHP_EOL;
        }
    ]
]));

$users_router->push(new Route([
    'name'        => 'user_by_name',
    'path'        => '/{name: string}',
    'controllers' => [
        'get' => function ($parameters) {
            echo 'User name: ' . $parameters->get('name') . PHP_EOL;
        }
    ]
]));

$router = new Router();
$router->push(new Route([
    'name'        => 'region,
    'path'        => '/{region: string}/user/',
    'controllers' => [
        'get' => function ($parameters) {
            echo 'Region: ' . $parameters->get('region') . PHP_EOL;
        }
    ]
    'sub_router' => $users_router
]));

$request = new Request('/victoria/user/21', 'get');
$route = $router->match($request);
$controller = $route->getController($request->getMethod());
$parameters = $route->getParameters();
$controller($route->getParameters());
// Region: victoria

$sub_router = $route->getSubRouter();
$sub_route = $sub_router->match($request);
$sub_controller = $sub_route->getController($request->getMethod());
$sub_controller($parameters);
// User id: 21

// Or using run method:
$router->run(new Request('/victoria/user/21', 'get'));
// Region: victoria
// User id: 21
```

License
-------

[](#license)

MIT © [Franz Neulist Carroll](mailto:franzneulistcarroll@gmail.com)

###  Health Score

20

—

LowBetter than 14% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity3

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

Unknown

Total

1

Last Release

3095d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9454ee303c98f5c2d2398d2f799b025a9908cfde0bdc1fc2cddd66b7e391264c?d=identicon)[rubberydub](/maintainers/rubberydub)

---

Top Contributors

[![luther7](https://avatars.githubusercontent.com/u/14562624?v=4)](https://github.com/luther7 "luther7 (115 commits)")

---

Tags

httpphprestrouterhttprestweb servicerouter

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/rubberydub-snout/health.svg)

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

###  Alternatives

[srmklive/paypal

Laravel plugin For Processing Payments Through Paypal Express Checkout. Can Be Used Independently With Other Applications.

1.1k3.8M26](/packages/srmklive-paypal)[e-moe/guzzle6-bundle

Integrates Guzzle 6 into your Symfony application

11259.2k](/packages/e-moe-guzzle6-bundle)[apoca/laravel-sibs-payments

Laravel library to communicate with SIBS - Open Payment Platform.

352.3k](/packages/apoca-laravel-sibs-payments)

PHPackages © 2026

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