Skip to content

romeOz/rock-route

Repository files navigation

Simple router for PHP

Latest Stable Version Total Downloads Build Status HHVM Status Coverage Status License

Features

  • Filters
  • Support REST
  • Groups
  • Inject arguments to action
  • Caching rules
  • Standalone module/component for Rock Framework

Table of Contents

Installation

From the Command Line:

composer require romeoz/rock-route

or in your composer.json:

{
    "require": {
        "romeoz/rock-route": "*"
    }
}

Quick Start

// url: http://site.com/items/7/        

$route = new Route();
 
$handler = function(Route $route){
    return 'id: ' . $route->getParam('id');
};
       
$route->get('/items/{id:\d+}/', $handler, ['as' => 'item']);
$route->post('/items/', ['\namespace\SomeController', 'actionCreate']);
$route->run();

// output: 'id: 7'

echo Alias::getAlias('@item', ['id' => 15]); 

// output: '/items/15/'

Pattern

You can use string or array as pattern.

$pattern = [
    Route::FILTER_HOST => '{sub:[a-z]+}.site.com',
    Route::FILTER_PATH => '/items/{id:\d+}/',
    Route::FILTER_GET => [
        'query' => true, 
        'view' => 'all', 
        'order' => 'sort-{order:(asc|desc)}'
    ]
]
$route->post($pattern, $handler);

'query' => true indicates that the URL-param query was mandatory.

Pattern as string /items/{id:\d+}/ is equivalent to [ Route::FILTER_PATH => '/items/{id:\d+}/' ].

Configurable

Set a rules you can as configurable. Can be useful for using inside your framework.

$config = [
    'rules' => [
        'item' => [Route::GET, '/items/{id:\d+}/', $handler]
    ]
]

$route = new Route($config);
$route->run();

For groups:

$config = [
    'groups' => [
        'api' => [
            [Route::GET, Route::POST],
            [ Route::FILTER_HOST => 'api.site.com' ],
            'rules' => [
                'item' => [Route::GET, '/items/{id:\d+}/', $handler]
            ]
        ]
    ]
]

$route = new Route($config);
$route->run();

Filters

For using filters you must be installed Rock Filters: composer require romeoz/rock-filters.

An example of disallow by IP (uses $_SERVER['REMOTE_ADDR']):

$route = new Route();
 
$handler = function(){
    return 'Hello world!';
};

$filters = [
    'access' => [
        'class' => '\rock\route\filters\AccessFilter',
        'rules' => [
            'allow' => true,
            'ips' => ['10.1.2.3']
        ]
    ]
]
       
$route->get('/items/{id:\d+}/', $handler, ['filters' => $filters]);
$route->run();

####Custom filter (as callable)

$filters = function(Route $route){
    return $route->request->isAjax();
};

Must returns true/false (boolean).

REST

$route = new Route();
      
$route->REST('items', 'ItemsController');
$route->run();

class ItemsController
{
    // GET /items/
    public function actionIndex()
    {
        return 'index';
    }

    // GET /items/7/
    public function actionShow()
    {
        return 'show';
    }

    // POST /items/
    public function actionCreate()
    {
        return 'create';
    }

    // PUT /items/7/
    public function actionUpdate()
    {
        return 'update';
    }

    // DELETE /items/7/
    public function actionDelete()
    {
        return 'delete';
    }
}

You can specify what actions to use (only or exclude):

$route->REST('items', 'ItemsController', ['only' => ['show', 'create']]);

Also you can specify custom REST scenario:

$config = [
    'RESTHandlers' => [
            'all' => [
                Route::GET,
                '/{url}/',
                ['{controller}', 'actionAll']
            ],
            'one' => [
                Route::GET,
                '/{url}/{id}/',
                ['{controller}', 'actionOne']
            ],
            'create' => [
                [Route::POST, Route::OPTIONS],
                '/{url}/',
                ['{controller}', 'actionCreate']  
            ],
            'update' => [
                [Route::PUT, Route::PATCH, Route::OPTIONS],
                '/{url}/{id}/',
                ['{controller}', 'actionUpdate']
            ],
            'delete' => [
                [Route::DELETE, Route::OPTIONS],
                '/{url}/{id}/',
                ['{controller}', 'actionDelete'] 
            ]    
    ]
];

$route = new Route($config);

Using groups

####Route prefixing

// url: http://site.com/api/items/7/  

$route = new Route();

$handler = function(Route $route) {
    $handler = function(Route $route){      
        return 'id: ' . $route['id'];
    };
    $route->get('/items/{id:\d+}/', $handler, ['as' => 'item']);
    return $route;
};

$route->group(Route::ANY, '/api/{url:.+}', $handler, ['path' => '/api/', 'as' => 'api']);
$route->run();

// output: 'id: 7'

echo Alias::getAlias('@api.item', ['id' => 15]); 

// output: '/api/items/15/'        

Here, the 'path' => '/api/' is the prefix for the rules of this group.

####Sub-Domain routing

// url: http://api.site.com/items/7/  

$route = new Route();

$handler = function(Route $route) {
    $handler = function(Route $route){      
        return 'id: ' . $route['id'];
    };
    $route->get('/items/{id:\d+}/', $handler, ['as' => 'item']);
    return $route;
};

$route->group(Route::ANY, [ Route::FILTER_HOST => 'api.site.com' ], $handler, ['as' => 'api']);
$route->run();

// output: 'id: 7'

echo Alias::getAlias('@api.item', ['id' => 15]); 

// output: 'api.site.com/items/15/'        

Alias for route

Using the as index of our route array you can assign a alias to a route:

$route->get('/items/{id:\d+}/', $handler, ['as' => 'item']);

echo Alias::getAlias('@item', ['id' => 15]); 

// output: '/items/15/'

Extended example:

$pattern = [
    Route::FILTER_HOST => '{sub:[a-z]+}.site.com',
    Route::FILTER_PATH => '/items/{id:\d+}/',
    Route::FILTER_GET => [
        'query' => true, 
        'view' => 'all', 
        'order' => 'sort-{order:(asc|desc)}'
    ]
]
$route->get($pattern, $handler, ['as' => 'item']);

echo Alias::getAlias('@item');

// output: {sub}.site.com/items/{id}/?view=all&order=sort-{order}

Also you can set a alias to group:

$route->group(
    Route::ANY, 
    [ Route::FILTER_HOST => 'api.site.com' ], 
    $handler, ['as' => 'api']
);

All rules belonging to this group will inherit this alias.

For configurable approach you can use the index:

$config = [
    'rules' => [
        'item' => [Route::GET, '/items/{id:\d+}/', $handler]
    ]
]

$route = new Route($config);

echo Alias::getAlias('@item'); 

// output: '/items/{id}/'

Using response

For using response you must be installed Rock Response: composer require romeoz/rock-response.

$response = new \rock\response\Response;
$route = new Route(['response' => $response]);

$handler = function(Route $route){
    $route->response->format = \rock\response\Response::FORMAT_JSON;
    return ['id' => $route->getParam('id')];
};

$route->get('/items/{id:\d+}/', $handler, ['as' => 'item']);
$route->run();
$response->send();

// output: {"id":7}

More details see docs

Inject arguments

$route = new Route;

$route->get('/', ['ItemsController', 'actionIndex'])
$route->run();

class ItemsController
{
    public function actionIndex(\rock\request\Request $request)
    {
        return $request::className();
    }
}

// output: 'rock\request\Request'

More flexible use is possible using the library Rock DI: composer require romeoz/rock-di.

For using you must be installed Rock Response: composer require romeoz/rock-response.

####Local

// url: http://site.com/news/7/        

$route = new Route();
 
$handler = function(Route $route){
    return 'hello';
};
       
$route->get('/foo/{id:\d+}/', $handler);
$route->post('/bar/{id:\d+}', ['\namespace\BarController', 'actionIndex']);
$route->run();

class BarController
{
    public function actionIndex(\rock\route\Route $route)
    {        
        $response = (new \rock\route\providers\Local(['route' => $route]))->send('http://site.com/foo/11/');
        return $response->getContent() . ' world!';
    }
}

// output: 'hello world!'

####Remote

For using you must be installed Guzzle: composer require guzzlehttp/guzzle:6.1.*.

Required PHP 5.5+

$response = (new \rock\route\providers\Remote())->send('http://site.com/foo/11/');

Caching rules

For caching rules/groups you must be installed Rock Cache: composer require romeoz/rock-cache.

$cache = new \rock\cache\Memcached;

$route = new Route([
    'cache' => $cache,
    'enableCache' => true
]);

For reset the cache using flushCache():

$route->flushCache();

Requirements

  • PHP 5.4+
  • For using response required Rock Response: composer require romeoz/rock-response
  • For using filters required Rock Filters: composer require romeoz/rock-filters
  • For using Rate Limiter filter required Rock Session: composer require romeoz/rock-session
  • For caching rules required Rock Cache: composer require romeoz/rock-cache
  • For using HMVC remote required Guzzle: composer require guzzlehttp/guzzle:6.1.*.

All unbolded dependencies is optional.

License

Router is open-sourced software licensed under the MIT license.