It's recommended that you use Composer to install Route.

$ composer require nezamy/route

Route requires PHP 5.4.0 or newer.


Create an index.php file with the following contents:

define('DS', DIRECTORY_SEPARATOR, true);
define('BASE_PATH', __DIR__ . DS, TRUE);

require BASE_PATH.'vendor/autoload.php';

$app		= System\App::instance();
$app->request  	= System\Request::instance();
$app->route	= System\Route::instance($app->request);

$route		= $app->route;

$route->any('/', function() {
    echo 'Hello World';


If using apache make sure the .htaccess file has exists beside index.php

How it works

Routing is done by matching a URL pattern with a callback function.

$route->any('/', function(){
    echo 'Hello World';

$route->any('/about', function(){
    echo 'About';

The callback can be any object that is callable. So you can use a regular function:

function pages(){
    echo 'Page Content';
$route->get('/', 'pages');

Or a class method:

class home
    function pages(){
        echo 'Home page Content';
$route->get('/', ['home', 'pages']);
// OR
$home = new home;
$route->get('/', [$home, 'pages']);
// OR
$route->get('/', 'home@pages');

Method Routing

$route->any('/', function(){
    // Any method requests

$route->get('/', function(){
    // Only GET requests

$route->post('/', function(){
    // Only POST requests

$route->put('/', function(){
    // Only PUT requests

$route->patch('/', function(){
    // Only PATCH requests

$route->delete('/', function(){
    // Only DELETE requests

// You can use multiple methods. Just add _ between method names.
$route->get_post('/', function(){
    // Only GET and POST request

Multiple Routing (All in one)

$route->get(['/', 'index', 'home'], function(){
    // Will match 3 page in one


// This example will match any page name.
$route->get('/?', function($page){
    echo "you are in $page";

// This example will match anything after post/ - limited to 1 argument.
$route->get('/post/?', function($id){
    // Will match anything like post/hello or post/5 ...
    // But not match /post/5/title
    echo "post id $id";

// More than parameters
$route->get('/post/?/?', function($id, $title){
    echo "post id $id and title $title";
you are in contact
post id 10 and title hello-world

For “unlimited” optional parameters, you can do this:

// This example will match anything after blog/ - unlimited arguments
$route->get('/blog/*', function(){
    // [$this] instanceof ArrayObject so you can get all args by getArrayCopy()
        [0] => /post/10
        [1] => post
        [2] => 10

Named Parameters

You can specify named parameters in your routes which will be passed along to your callback function.

$route->get('/{username}/{page}', function($username, $page){
    echo "Username $username and Page $page <br>";
    // OR
    echo "Username {$this['username']} and Page {$this['page']}";
Username mahmoud.elnezamy and Page profile
Username mahmoud.elnezamy and Page profile

Regular Expressions

You can validate the args by regular expressions.

// Validate args by regular expressions uses :(your pattern here)
function($username, $id)
    echo "author $username post id $id";

// You can add named regex pattern in route
    'username' => '/([0-9a-z_.-]+)',
    'id' => '/([0-9]+)'

// Now you can use named regex
$route->get('/{username}:username/post/{id}:id', function($username, $id){
    echo "author $username post id $id";

Some named regex pattern already registered in routes

    'int'               => '/([0-9]+)',
    'multiInt'          => '/([0-9,]+)',
    'title'             => '/([a-z_-]+)',
    'key'               => '/([a-z0-9_]+)',
    'multiKey'          => '/([a-z0-9_,]+)',
    'isoCode2'          => '/([a-z]{2})',
    'isoCode3'          => '/([a-z]{3})',
    'multiIsoCode2'     => '/([a-z,]{2,})',
    'multiIsoCode3'     => '/([a-z,]{3,})'

Optional parameters

You can specify named parameters that are optional for matching by adding (?)

function($title, $date){
        echo "<h1>$title</h1>";
        echo "<h1>Posts List</h1>";

        echo "<small>Published $date</small>";


Published 2016


$route->group('/admin', function()
    // /admin/
    $this->get('/', function(){
        echo 'welcome to admin panel';

    // /admin/settings
    $this->get('/settings', function(){
        echo 'list of settings';

    // Nested group
    $this->group('/users', function()
        // /admin/users
        $this->get('/', function(){
            echo 'list of users';

        // /admin/users/add
        $this->get('/add', function(){
            echo 'add new user';

    // Anything else
    $this->any('/*', function(){
        pre("Page ( {$this->app->request->path} ) Not Found", 6);

Groups with parameters

$route->group('/{lang}?:isoCode2', function($lang)
    $default = $lang;

    if(!in_array($lang, ['ar', 'en'])){
        $default = 'en';

    $this->get('/', function($lang) use($default){
        echo "lang in request is $lang<br>";
        echo "include page_{$default}.php";

    $this->get('/page/{name}/', function($lang, $name)
lang in request is
include page_en.php
lang in request is ar
include page_ar.php
lang in request is fr
include page_en.php
    [0] =>    [1] => about
    [lang] =>    [name] => about
    [0] => ar
    [1] => about
    [lang] => ar
    [name] => about

Route name

$route->any('/', function(){
    // You can get the route name by
    // echo $this->app->route->getRoute('about');
    // OR by shortcut function
    echo route('about');

$route->any('/about', function(){
    echo route('home');

Route name with args

$route->any('/page/{pagename}', function() {
    echo route('') .'<br>';
    echo route('', ['pagename' => 'ThePageName']);

$route->group('/{lang}', function($lang) {
    $this->get('/', function($lang) {
        echo route('', [
            'lang'  => 'ar',
            'name'   => 'ThePageName'

    $this->get('/page/{name}/', function($lang, $name) {
        echo route('home', ['lang' => $name]);

Shortcut functions

pre();  // print string or array for debug
dpre(); // the same pre() with die();
br();   // echo string with new line by <br> html tag
app();  // app instance
route();// shortcut for Route::getRoute()
url();  // OR URL constant get domain url


// Variables
app()->x = 'something';
echo app()->x; // something
// OR
echo app('x'); // something

// Functions
app()->calc = function($a, $b){
    echo $a + $b;
echo app()->calc(5, 4); //9

// Classes
class myClass {

app()->myClass = new myClass;
pre( app('myClass') );


app('request')->server; //$_SERVER
app('request')->path; // uri path
app('request')->protocol; // http or https
app('request')->url; // domain url
app('request')->curl; // current url
app('request')->extension; // get url extension
app('request')->headers; // all http headers
app('request')->method; // Request method
app('request')->query; // $_GET
app('request')->body; // $_POST and php://input
app('request')->args; // all route args
app('request')->files; // $_FILES
app('request')->cookies; // $_COOKIE
app('request')->ajax; // check if request is sent by ajax or not
app('request')->ip(); // get client IP
app('request')->browser(); // get client browser
app('request')->platform(); // get client platform
app('request')->isMobile(); // check if client opened from mobile or tablet

// You can append vars functions classes to request class
app('request')->addsomething = function(){
    return 'something';


Use namespace like folder name and make sure the file name is same the class name.

namespace App;
class homeController
    public function index()
        # code...

// Call the class with a namespace

$route->get('/', 'App\homeController@index');

Copyright © 2016 Mahmoud Elnezamy | All Rights Reserved