Routers

A PHP router is a component or script in a web application that directs incoming HTTP requests to the appropriate handler or controller based on predefined rules. Read more about it here.

MaplePHP is built upon nikic/FastRoute, but MaplePHP has added additional functionality. FastRoute works exceptionally well and employs regular expressions for advanced users. You can add your routers in "app/Http/Routes/web.php" or create your own like "api.php" and so on.

Bind controller to request

Like most other frameworks and routers, you can bind HTTP requests to different methods:

HTTP GET Request

$routes->get("/{page:about}", ['Http\Controllers\Pages', "about"]);

HTTP POST Request

$routes->post("/{page:about}", ['Http\Controllers\Pages', "about"]);

HTTP PUT Request

$routes->put("/{page:about}", ['Http\Controllers\Pages', "about"]);

HTTP DELETE Request

$routes->delete("/{page:about}", ['Http\Controllers\Pages', "about"]);

HTTP Custom Request

$routes->map("GET", "/{page:about}", ['Http\Controllers\Pages', "about"]);

HTTP Multiple Requests

$routes->map(["GET", "POST"],"/{page:about}", ['Http\Controllers\Pages', "about"]);

Grouping

What really makes MaplePHP unique is its group function, where you can group on both or just one of the URI pattern and middlewares:

Group with URI Path Pattern

$routes->group("/{lang:en}", function($routes) {
    $routes->get("/{page:about}", ['Http\Controllers\Pages', "about"]);
    $routes->get("/{page:contact}", ['Http\Controllers\Pages', "contact"]);
});

The URI Path Pattern example shown above is a basic example but will likely be the one you use the most. However, there are more advanced patterns that I will show below.

Group with middlewares

$routes->group(function($routes) {
    $routes->get("/{page:about}", ['Http\Controllers\Pages', "about"]);
    $routes->get("/{page:contact}", ['Http\Controllers\Pages', "contact"]);
}, [
    MaplePHP\Foundation\Auth\Middleware\SessionStart::class,
    [Http\Middlewares\Document::class, ["after" => ["head", "navigation", "footer"]]]
]);

Why would you want to group with middlewares? This design is user-friendly and pedagogical, providing an efficient way to add functionality and improve performance by loading only the necessary extras. The above example starts a session and adds navigation to the pages. This way, you can for example incorporate multiple different navigations.

Group with both Pattern and Middleware

$routes->group("/{lang:en}", function($routes) {
    $routes->get("/{page:about}", ['Http\Controllers\Pages', "about"]);
    $routes->get("/{page:contact}", ['Http\Controllers\Pages', "contact"]);
}, [
    MaplePHP\Foundation\Auth\Middleware\SessionStart::class,
    [MaplePHP\Foundation\Auth\Middleware\LoggedIn::class, "PublicZone"],
    [Http\Middlewares\Document::class, ["after" => ["head", "navigation", "footer"]]]
]);

A before and after method will be called in each middleware, meaning before and after the grouped routes controller has been executed. However, you can also bind a specific method to the before call, as demonstrated above with PublicZoneand the Document class.

You can probably see now what makes MaplePHP Routing so user-friendly.

Nesting group

What makes MaplePHP truly great is that you can also group already grouped routes endlessly.


// User integrity policy page do not need a session
$routes->get("/{page:policy}", ['Http\Controllers\Pages', "policy"]);

// Start a session
$routes->group(function($routes) {
    
    $routes->group(function($routes) {
        $routes->get("/{page:login}", ['Http\Controllers\Pages', "LoginForm"]);
        $routes->post("/{page:login}", ['Http\Controllers\Pages', "LoginValidate"]);
    }, [
        // If logged in then it will redirect user to "privateZone"
        [MaplePHP\Foundation\Auth\Middleware\LoggedIn::class, "publicZone"]
    ]);
    
    $routes->group(function($routes) {
        $routes->get("/{page:dashboard}", ['Http\Controllers\Private\Pages', "dashboard"]);
        $routes->get("/{page:profile}", ['Http\Controllers\Private\Pages', "profile"]);
    }, [
        // If logged out then it will redirect user to "publicZone"
        [MaplePHP\Foundation\Auth\Middleware\LoggedIn::class, "privateZone"],
        // Only add navigation to logged in pages
        [Http\Middlewares\Document::class, ["after" => ["navigation"]]]
    ]);
    
}, [
    MaplePHP\Foundation\Auth\Middleware\SessionStart::class,
    [Http\Middlewares\Document::class, ["after" => ["head", "footer"]]]
]);

Patterns

It is possible to use Regular Expression (Regex). Form more information you can also click here.

/param1
/param1/param2/param3

It is, however, recommended to at least bind a URI path to a pattern key. This is because you can later very easily extract the path with MaplePHP Url (UrlInterface) instance.

/{page:param1}
/{page:param1/param2/param3}

Advanced patterns

Find all, strings and numbers (counts as one parameter)

[^/]+

Allow only numbers

\d+

Find everything for dynamic parameters

.+

IF match or else

(?:match|elseMatch)

It is also highly recommended to attach a KEY to a pattern. With the example above you can write more complete routes like bellow.

/{page:param1}
/{page:[^/]+}
RESULT:
OK: /about-us
NOT_FOUND: /about-us/environment
/{page:[^/]+}/{subpagePage:[^/]+}
RESULT:
OK: /about-us/environment
/{page:.+}
RESULT:
OK: /about-us/environment
/{page-id:\d+}
RESULT:
OK: /5242
NOT_FOUND: /about-us
/{product-id:\d+}/{slug:[^/]+}
RESULT:
OK: /5242/round-table
/{cat:.+}[/{pagination:pagin-\d+}]
RESULT:
OK: /cat1/cat2/.../cat5
OK: /cat1/cat2/.../cat5/pagin-2

Add a new router file

You might want to add a new router file to organize your routes. You do this by editing the "config/routers.php" file:

<?php

/**
 * Config file
 * @psalm-suppress InvalidScope
 */

return [
    'routers' => [
        'load' => ["web", "cli", "yourCustomRouterFile"],
        "cache" => true,
        'cacheFile' => [
            //'driver' => 'file',
            'path' => 'storage/caches/',
            'file' => 'router.cache',
            'prefix' => 'maple_'
        ]
    ]
];

Last updated