PHP Luminova: Request Routing Handler
Luminova's routing module simplifies capturing, processing, and executing both web page and CLI command requests within your controller class.
Routing is an essential part of the Luminova framework to handle incoming URI requests and matches them to the right controller methods. Its also manages request middleware authentication based on the URI prefix and patterns.
Luminova simplifies and speeds up routing by using a Routing URI Prefix to quickly match the initial part of the URI as context and load the routes/<context>.php
to handle request controller routing. This means only the necessary routes are loaded, improving performance compared to loading all routes in a single context.
The routing module works efficiently for both HTTP
and CLI
requests, it captures and matches URI patterns, handles commands, and manages authentication with middleware as needed.
In Luminova routing, routable controller methods support dependency injection. This means you can specify the types of modules you want as parameters in your controller methods. By default, this feature is disabled. To enable it, update your environment configuration file setting the value of feature.route.dependency.injection
to enable
.
Defining Controller Method
When defining controller methods or rendering callback handlers, you can use either a Closure
or a string format that resembles a static method call (e.g., ControllerBaseName::methodName
). The key difference is that you don’t need to specify the full class namespace, as it has already been registered in your application. You only need to provide the class base name and the method name (e.g., ControllerBaseName::methodName
).
Segment Capturing
Segment capturing is way to capture URL segments and pass them to controller as arguments for further processing, the capture pattern uses various methods like regular expression patterns (e.g., /foo/([a-zA-Z0-9]+)/([0-9]+)
), named placeholders (e.g., /foo/{title}/{id}
), or predefined strict placeholders (e.g., /foo/(:string)/(int)
). While regular expressions offer flexibility, named and strict placeholders provide a more convenient and developer-friendly approach, making them especially suitable for beginners.
View Caching
To learn about how Luminova view caching and static content serving work read the documentation.
PHP Attributes
Luminova provides a Route
attribute, allowing you to define both HTTP
and CLI
routes using attributes. Read the documentation here.
Base Usages
In your route context file /routes/<context>.php
, the variable holding Luminova\Routing\Router $router
and App\Application $app
object is already available as a global variable. Therefore, there's no need to specify the use
keyword or import the router instance anymore except if it required which is usually for bind
or group
method.
// /routes/web.php
$router->get('/', function (Application $app) {
return $app->view('index')->render([
'foo' => 'Bar' // Options to pass to the view
]);
});
Using Controller Class
When passing your controller class, you only need to provide the class base name and method, without the full namespace (e.g., ExampleController::about
) instead of App\Controllers\Http\ExampleController
. The namespace is already registered with the CoreApplication
class, allowing you to pass only a controller class that extends Luminova\Base\BaseController
by default.
// /routes/web.php
$router->get('/about', 'ExampleController::about');
Bind Group
If you need to register a URI group for routing, you can use bind
method which accepts only 2
arguments group pattern
and Closure
.
// /routes/web.php
use \Luminova\Routing\Router;
use \Luminova\Core\CoreApplication;
$router->bind('/blog', function(Router $router, CoreApplication $app) {
$router->middleware('GET', '/(:root)', 'Authentication::isAllowed');
$router->get('/', 'ExampleController::blogs');
$router->get('/(:alphanumeric)', 'ExampleController::blog');
});
Capturing Any HTTP Method
The any
method allows you to capture any HTTP
request method, which is especially useful for AP
I applications.
For example, to handle all HTTP methods for a "Contact Us" page:
// /routes/web.php
$router->any('/contact', 'ExampleController::contact');
Alternatively, you can achieve the same functionality using the capture
method with Router::ANY_METHODS
or ANY
:
// /routes/web.php
$router->capture('ANY', '/contact', 'ExampleController::contact');
Using capture
for selective HTTP
methods.
// /routes/web.php
$router->capture('POST|GET|PUT', '/contact', 'ExampleController::contact');
Dependency Injection
Luminova routing supports dependency injection for controller methods. You can type-hint dependencies either in class methods or in callback functions to render your views.
Using Controller Class Method:
// /app/Controllers/Http/ExampleController.php
namespace App\Controllers\Http;
use Luminova\Base\BaseController;
class ExampleController extends BaseController
{
public function userInfo(Request $request): int
{
$name = $request->getGet('name');
// Method implementation
}
}
Using Callback Function:
// /routes/web.php
use Luminova\Http\Request;
$router->get('/users', function (Request $request) {
$name = $request->getGet('name');
// Callback implementation
});
In both examples, the Request
object is automatically injected into the method, allowing you to access request data directly.
Command Controller
Registering command controller routing.To register commands, you will need to first call the group
method which is like your command base, within the group closure you can then call command
method to register your commands associated to the group name.
// /routes/cli.php
use \Luminova\Routing\Router;
use \Luminova\Core\CoreApplication;
use \Luminova\Command\Terminal;
$router->group("blog", function(Router $router, CoreApplication $app) {
$router->command("list", 'Command::listBlogs');
$router->command('id/(:int)', 'Command::showBlog');
});
To execute the above command run the following command:
To list all blogs based on the above example.
php index.php blog list
To get a single blog by its ID based on the above example.
php index.php blog id=2
Class Definition
- Class namespace:
\Luminova\Routing\Router
- This class is marked as final and can't be subclassed
Methods
Explore additional usage examples in the Routing Example Documentation. For insights on using Dynamic Segment Strict Placeholders in Routing, visit the dedicated guide.
context
Initialize application routing with supported context URI prefixing web
, cli
, api
, console
etc...
The context
method is a crucial part of routing optimization in Luminova. It initializes your routes based on the request URL path prefix. This method is called once at runtime in your application's entry point, typically /public/index.php
.
The context
method allows you to define URI prefixes and error handlers for specific URI prefixes. This ensures that only the necessary routes for handling requests are loaded based on the URL prefix, such as api
, console
, and more. The default context name web
handles any incoming request without a unique registered prefix.
This method is flexible in its argument approach, supporting a Context
object, an array, or null
when using PHP attributes instead of code-based routing.
Using an array is particularly useful for scenarios with complex routing requirements or a large number of contexts. It offers better scalability and maintainability. Choose the method that best aligns with your specific use case and coding style preferences.
public context(\Luminova\Routing\Prefix|array<string,mixed>|null ...$contexts): self
Parameters:
Parameter | Type | Description |
---|---|---|
$contexts | Luminova\Routing\Prefix|array<string,mixed>|null | Arguments containing routing prefix or an array of arguments. Pass null or leave blank only when using route attributes. |
Return Value
self
- Return router instance class.
Throws:
- \Luminova\Exceptions\RouterException - Thrown if no context arguments are passed and route attributes are not enabled.
See Also:
- Routing URL Prefix - Learn more about how routing prefixes work and their usage.
- Index Controller Handler - See an example of the front controller index file handler.
Note:The prefix name must be unique based on your
URLs
to discover and load only the required files.Additionally, mixing context arguments with arrays andContext
instances may produce unintended errors.
HTTP Router Method
The HTTP router methods are named after common HTTP
methods to make them simple and easy to understand. These methods help you define routes for different HTTP requests in a clear and intuitive way.
get
Get, a shorthand for route capture
method to handle GET
request method.
public get(string $pattern, \Closure|string $callback): void
Parameters:
Parameter | Type | Description |
---|---|---|
$pattern | string | The route URL pattern or template name (e.g., / , /home , /user/([0-9]) or /user/(:placeholder) ). |
$callback | \Closure|string | The callback to execute (e.g., ClassBaseName::methodName ). |
post
Post, a shorthand for route capture
method to handle POST
request method.
public post(string $pattern, \Closure|string $callback): void
Parameters:
Parameter | Type | Description |
---|---|---|
$pattern | string | The route URL pattern or template name (e.g., / , /home , /user/([0-9]) or /user/(:placeholder) ). |
$callback | \Closure|string | The callback to execute (e.g., ClassBaseName::methodName ). |
patch
Patch, a shorthand for route capture
method to handle PATCH
request method.
public patch(string $pattern, \Closure|string $callback): void
Parameters:
Parameter | Type | Description |
---|---|---|
$pattern | string | The route URL pattern or template name (e.g., / , /home , /user/([0-9]) or /user/(:placeholder) ). |
$callback | \Closure|string | The callback to execute (e.g., ClassBaseName::methodName ). |
delete
Delete, a shorthand for route capture
method to handle DELETE
request method.
public delete(string $pattern, \Closure|string $callback): void
Parameters:
Parameter | Type | Description |
---|---|---|
$pattern | string | The route URL pattern or template name (e.g., / , /home , /user/([0-9]) or /user/(:placeholder) ). |
$callback | \Closure|string | The callback to execute (e.g., ClassBaseName::methodName ). |
put
Put, a shorthand for route capture
method to handle PUT
request method.
public put(string $pattern, \Closure|string $callback): void
Parameters:
Parameter | Type | Description |
---|---|---|
$pattern | string | The route URL pattern or template name (e.g., / , /home , /user/([0-9]) or /user/(:placeholder) ). |
$callback | \Closure|string | The callback to execute (e.g., ClassBaseName::methodName ). |
options
Options, a shorthand for route capture
method to handle OPTIONS
request method.
public options(string $pattern, \Closure|string $callback): void
Parameters:
Parameter | Type | Description |
---|---|---|
$pattern | string | The route URL pattern or template name (e.g., / , /home , /user/([0-9]) or /user/(:placeholder) ). |
$callback | \Closure|string | The callback to execute (e.g., ClassBaseName::methodName ). |
middleware
Registers an HTTP before
middleware to authenticate requests before handling controllers.
This method allows you to apply middleware security logic that executes prior to any associated HTTP controllers. If the middleware callback returns STATUS_ERROR
, the routing process will terminate, preventing further execution.
Middlewares can be registered within a bind
method for a specific URI prefix or in the global scope of the routing context. It also support defining regular expression patterns and methods to match before executing.
public middleware(string $methods, string $pattern, \Closure|string $callback): void
Parameters:
Parameter | Type | Description |
---|---|---|
$methods | string | The allowed HTTP methods, separated by a &#124; pipe symbol (e.g,. GET&#124;POST ). |
$pattern | string | The route URL pattern or template name (e.g., /.* , /home , /user/([0-9]) or /user/(:placeholder) ). |
$callback | \Closure|string | The callback function or controller method to execute. |
Throws:
- \Luminova\Exceptions\RouterException - Thrown if the method is called in non-HTTP context or the
$methods
parameter is empty.
guard
Registers a CLI before
middleware guard to authenticate commands within a specific group.
The guard
method provides middleware security for CLI
implementation. It applies middleware logic to CLI commands within a specified group. The middleware is executed before any command in the group. If the response code returns STATUS_SUCCESS
, the routing process will continue to execute other commands. If the middleware callback returns STATUS_ERROR
, the routing process will terminate, preventing further commands from executing.
Unlike the middleware
method, which handles only HTTP
method authentication and accepts regular regex
patterns, the guard
method accepts only the command group name or global
for global middleware security.
public guard(string $group, \Closure|string $callback): void
Parameters:
Parameter | Type | Description |
---|---|---|
$group | string | The command group name or default global for middleware that applies to all commands. |
$callback | \Closure|string | The callback function or controller method to execute (e.g., ControllerClass::methodName ). |
Throws:
- \Luminova\Exceptions\RouterException - Thrown if the method is used outside a CLI context.
Note: To register middleware with the group name, you must define your
guard
method within thegroup
method callback closure.
after
Registers an HTTP "after" middleware to execute logic after a controller has been handled.
This method applies middleware logic that runs after a controller processes a request. It is typically used for tasks such as cleanup or additional post-processing.
public after(string $methods, string $pattern, \Closure|string $callback): void
Parameters:
Parameter | Type | Description |
---|---|---|
$methods | string | The allowed HTTP methods, separated by a &#124; pipe symbol (e.g., GET&#124;POST ). |
$pattern | string | The route URL pattern or template name (e.g., / , /home , /user/([0-9]) ). |
$callback | \Closure|string | The callback function or controller method to execute (e.g., ClassBaseName::afterMethodName ). |
Throws:
- \Luminova\Exceptions\RouterException - Thrown if the
$methods
parameter is empty.
Note: This method can only be used on
HTTP
request routing, it not allowed inCLI
mode.
capture
Registers HTTP request methods, URI patterns, and corresponding callback or controller methods.
This method allows you to define routes by specifying supported HTTP methods, a URL pattern, and the callback or controller method to execute when the pattern matches a client request. Multiple HTTP methods can be specified using the pipe (|
) symbol.
public capture(string $methods, string $pattern, \Closure|string $callback): void
Parameters:
Parameter | Type | Description |
---|---|---|
$methods | string | The allowed method(s), multiple HTTP methods can be separated by &#124; pipe symbol (e.g., GET\|POST\|PUT or ANY ). |
$pattern | string | The route URL pattern or template name (e.g., / , /home , /user/([0-9]) or /user/(:placeholder) ). |
$callback | \Closure|string | The callback function or controller method to execute (e.g., ClassBaseName::methodName ). |
Throws:
- \Luminova\Exceptions\RouterException - Thrown if an empty method string is provided.
command
Registers a CLI command and its corresponding callback or controller method.
This method is used to define CLI commands, specifying the command name and the callback function or controller method to execute when the command is run in the terminal. Unlike HTTP routes, CLI commands are defined using this method specifically within a group
method and does not support regular regex patterns. Instead, it uses a set of filter rules to capture command arguments.
public command(string $command, \Closure|string $callback): void
Parameters:
Parameter | Type | Description |
---|---|---|
$command | string | The command group name or a command group name with filters (e.g., foo , foo/(:int)/bar/(:string) ). |
$callback() | \Closure|string | The callback function or controller method to execute (e.g., ClassBaseName::methodName ). |
Example Usage:
Suppose you have a command group blogs
and a blog command controller class with two methods: list
and get
. The list
method accepts an int
argument to determine the number of blogs to list, while the get
method accepts a string
as the blog ID. You can register these commands with filters like /list/limit/(:int)
for the list method and /get/id/(:string)
for the get method.
List Command:
$router->group('blog', function(Router $router){
$router->command('/list/limit/(:int)', 'BlogCommandController::list');
});
List Command With Attribute:
// /App/Controllers/Cli/BlogCommandController.php
#[Route('list/limit/(:int)', group: 'blog')]
public function list(int $limit = 10): int
{}
Get Command:
$router->group('blog', function(Router $router){
$router->command('/get/id/(:string)', 'BlogCommandController::get');
});
Get Command With Attribute:
// /App/Controllers/Cli/BlogCommandController.php
#[Route('get/id/(:string)', group: 'blog')]
public function get(string $id): int
{}
Note:For commands that don't expect any arguments, you don't need to add any filters, just pass the name like
foo
.Additionally, execution of the command controller must follow this pattern:
php index.php <command-group> <command> <argument>
.
any
Capture and handle requests for any HTTP method.
This method leverages Router::ANY_METHODS
to match and handle requests for any HTTP method. It is a convenient way to define routes that respond to all HTTP methods without explicitly specifying them.
public any(string $pattern, \Closure|string $callback): void
Parameters:
Parameter | Type | Description |
---|---|---|
$pattern | string | The route URL pattern or template name (e.g., / , /home , /user/([0-9]) ). |
$callback | \Closure|string | The callback function or controller method to execute (e.g., ClassBaseName::methodName ). |
bind
Groups related routes under a specified URI prefix.
The bind
method simplifies route organization by associating a group of routes with a common base path or pattern. It allows you to define and manage multiple nested URI
patterns under a shared prefix, enhancing the clarity and maintainability of your routing structure. Additionally, middleware can be applied within the scope of the defined closure, enabling advanced route-specific logic.
public bind(string $prefix, \Closure $callback): void
Parameters:
Parameter | Type | Description |
---|---|---|
$prefix | string | The base path or URI pattern (e.g,. /blog , /account/([a-z]) or /account/(:placeholder) ). |
$callback | \Closure | The closure containing the route definitions for the group. |
Example:
Using bind
to group routes under a /blog
prefix:
$router->bind('/blog/', static function (Router $router) {
$router->get('/', 'BlogController::listBlogs'); // Matches '/blog/'
$router->get('/([a-zA-Z0-9-]+)', 'BlogController::readBlog'); // Matches '/blog/{slug}'
$router->get('/edit/([a-zA-Z0-9-]+)', 'BlogController::editBlog'); // Matches '/blog/edit/{slug}'
});
Explanation:
When you group routes using bind
, the specified prefix (e.g., /blog
) is prepended to all routes defined within the closure. For example:
http://example.com/blog/
maps tolistBlogs
.http://example.com/blog/{slug}
maps toreadBlog
.http://example.com/blog/edit/{slug}
maps toeditBlog
.
This approach keeps route definitions organized and manageable, especially for applications with multiple related endpoints. Additionally, middleware can be applied selectively within the closure to handle group-specific logic.
group
Organizes CLI commands into a specific group for execution.
Similar to the HTTP bind
method, the group
method simplifies the organization of CLI commands by grouping related commands under a common name. This is especially useful for commands related to the same controller, making it easier to execute and maintain them.
public group(string $group, \Closure $callback): void
Parameters:
Parameter | Type | Description |
---|---|---|
$group | string | The name of the command group (e.g., blog , user ). |
$callback | \Closure | A callback function that defines the commands for the group. |
Example:
Grouping CLI commands under a blog
group:
$router->group('blog', static function (Router $router) {
$router->command('list', 'BlogController::blogs'); // Command to list all blogs
$router->command('id/(:int)', 'BlogController::blog'); // Command to fetch a blog by ID
});
Executing Commands:
# Navigate to the project's public directory
cd path/to/project/public/
# Execute commands within the `blog` group
php index.php blog list # Lists all blogs
php index.php blog id=4 # Fetches the blog with ID 4
Note: Ensure that the group name matches the name defined in the controller class
$group
property value to avoid errors.
addNamespace
Registers an MVC
or HMVC
controller namespace group for application routing.
This method allows the registration of new routable namespaces, making controllers within those namespaces accessible for routing in both HMVC and MVC applications.
Namespace Pattern:
Register your namespace up to the controller path, excluding the Http
and Cli
suffixes.
- HMVC Example: Use
\App\Modules\FooModule\Controllers\
instead of\App\Modules\FooModule\Controllers\Http
.
This allows the router to capture bothHttp
andCli
namespaces under the registered group.
public addNamespace(string $namespace): self
Parameters:
Parameter | Type | Description |
---|---|---|
$namespace | string | The namespace to register (e.g., \App\Controllers\ , \App\Modules\FooModule\Controllers\ ). |
Return Value:
self
- Returns the instance of the router class.
Throws:
- \Luminova\Exceptions\RouterException - If the namespace is empty or invalid.
Example:
Registering namespaces for module controllers:
This setup is typically implemented in your application class, either within the constructor
or the onCreate
method.
// /app/Application.php
namespace App;
use Luminova\Core\CoreApplication;
class Application extends CoreApplication
{
protected function onCreate(): void
{
// Register HMVC module namespaces
$this->router->addNamespace('\\App\\Modules\\Admins\\Controllers\\');
$this->router->addNamespace('\\App\\Modules\\Users\\Controllers\\');
}
}
Note: For MVC and HMVC applications, base controllers are already defined in the Luminova\Core\CoreApplication
class. Use addNamespace
only to extend routing for additional modules or custom namespaces.
run
Run application by matching and processing incoming HTTP or CLI requests against registered routes.
This method iterates through all defined routes, identifies the matching URI and HTTP method (or CLI command), and dispatches the request to the appropriate controller method. It also integrates application profiling and triggers lifecycle events for a smooth termination.
Key Features:
- HTTP Request Handling: Supports handling HTTP requests and static caching.
- CLI Compatibility: Supports handling CLI command execution similar with HTTP handling.
- Profiling Integration: Computes and sends profiling data to the UI for rendering.
- Lifecycle Management: Handles all application routing lifecycle and executes the
onFinish
event before the application terminates.
public run(): void
Throws:
- \Luminova\Exceptions\RouterException - Thrown if an error occurs during request processing or route resolution.
Example:
This method is typically executed in the front controller (/public/index.php
) to initialize and run the application context.
// /public/index.php
declare(strict_types=1);
use Luminova\Boot;
require_once __DIR__ . '/../system/Boot.php';
// Ensure the script is running from the front controller in CLI mode
if (getcwd() . DIRECTORY_SEPARATOR !== FRONT_CONTROLLER) {
chdir(FRONT_CONTROLLER);
}
// Initialize and run the application context
Boot::http()->router->context()->run();
Notes: The
run
method is designed to be invoked after initializing thecontext
method. Ensure this is done in the front controller to handle incoming requests seamlessly.
setErrorListener
Set the handler context error listener for 404
errors.
public setErrorListener(\Closure|string|array $match, \Closure|array|null $callback = null): void
Parameters:
Parameter | Type | Description |
---|---|---|
$match | \Closure|string|array<int,string> | Matching route callback or segment pattern for error handling. |
$callback | \Closure|string|array<int,string>|null | Optional error callback handler function. |
Throws:
- \Luminova\Exceptions\RouterException - EThrows if callback is specified and
$match
is not a segment pattern.
If the
$match
parameter is passed a callback handler and$callback
parameter is passedNULL
, then the handler will trigger the error callback whenever any404
error occurred within the routing prefix context.To define a custom error based on
group
orpatterns
, You must define your match patterns before callback method or closure.
triggerError
To manually trigger an error handler.This method can be used anywhere in controller class $this->app->router->triggerError()
or routing context $router->triggerError();
.
public triggerError(int $status = 404): void
Parameters:
Parameter | Type | Description |
---|---|---|
$status | int | HTTP response status code (default: 404) |
getBase
To get application public controller base path.
public getBase(): string
Return Value:
string
- Return base path.
getSegment
To access more information about the requested URI
segments.
public getSegment(): \Luminova\Routing\Segments
Return Value:
Segments
- Return URL segment instance
See Also
View Segment Instance - Helper class to retrieve view segments.