Router
in package
Lightweight routing engine with dual CLI and HTTP support plus comprehensive middleware
Provides URL routing capabilities for both web applications and command-line interfaces within a single unified system. Features dynamic route registration, named parameter extraction, middleware pipeline execution, and extensive event integration for monitoring and debugging routing operations.
Core Architecture
- Static Factory Pattern: All functionality accessed via static methods
- Singleton Behavior: Single global routing state shared across application
- Dual Context Support: Seamlessly handles HTTP requests and CLI commands
- Event Integration: Comprehensive EventManager integration for monitoring
- Middleware Pipeline: Ordered middleware execution with result handling
Routing Features
- HTTP Method Support: GET, POST, PUT, DELETE with proper RESTful semantics
- CLI Command Routing: Command-line interface routing with argument parsing
- Named Parameters: Dynamic URL segments with automatic extraction
- Route Patterns: Flexible pattern matching with regex conversion
- Route Normalization: Consistent path handling across contexts
- 404 Handling: Customizable not-found responses for HTTP and CLI
Middleware System
- Pipeline Execution: Ordered middleware chain before route handlers
- Result Handling: Support for redirects, errors, and flow control
- Context Awareness: Middleware receives method, path, and parameters
- Early Termination: Middleware can halt execution with redirects or errors
- Event Tracking: Before/after events for each middleware execution
Parameter Extraction
- Named Segments: Routes like
/user/{id}
extract parameters automatically - Type Safety: Parameters passed as array values to handlers
- CLI Arguments: Command-line arguments merged with extracted parameters
- Pattern Matching: Regex-based parameter extraction from URL paths
Event Integration
Router fires comprehensive events via EventManager for monitoring:
router.init
: Fired during initialization with method and pathrouter.middleware.before/after
: Middleware execution trackingrouter.middleware.redirecting
: When middleware triggers redirectsrouter.middleware.error
: When middleware returns error responsesrouter.dispatching/dispatching.cli
: Route handler executionrouter.404/404.no_callback
: 404 handling scenarios
Tags
Table of Contents
Properties
- $method : string
- Current request method determined during router initialization
- $page404 : callable|null
- Custom 404 handler callback for unmatched routes
- $path : string
- Normalized request path used for route pattern matching
- $routes : array<string, array<string, array{original: string, params: string[], middleware: string[], callback: callable}>>
- Master registry of all registered routes organized by HTTP method and CLI
Methods
- __wakeup() : mixed
- Prevent unserialization of Router class
- cli() : void
- Register CLI command route with middleware pipeline and handler callback
- delete() : void
- Register DELETE route with middleware pipeline and handler callback
- dispatch() : void
- Process current request by matching routes, executing middleware, and calling handlers
- get() : void
- Register GET route with middleware pipeline and handler callback
- init() : void
- Initialize routing engine by detecting execution context and extracting request details
- listRoutes() : array<string|int, array{method: string, route: string, middleware: string[]}>
- Retrieve complete list of registered routes with metadata
- page404() : void
- Set custom 404 handler for unmatched routes
- post() : void
- Register POST route with middleware pipeline and handler callback
- printRouteList() : void
- Output HTML table of registered routes for browser-based debugging
- put() : void
- Register PUT route with middleware pipeline and handler callback
- __clone() : mixed
- Prevent cloning of Router class
- __construct() : mixed
- Prevent instantiation of Router class
- addRoute() : void
- Internal route registration with pattern conversion and data storage
- normalizeCliRoute() : string
- Normalize CLI command routes by removing slashes and whitespace
- normalizeRoute() : string
- Normalize HTTP routes by standardizing slash handling and format
- routeToRegex() : array{0: string, 1: string[]}
- Convert route pattern to regex and extract parameter names
Properties
$method
Current request method determined during router initialization
private
static string
$method
Stores the HTTP method (GET, POST, PUT, DELETE) for web requests or 'CLI' for command-line execution. Set during init() based on environment detection and used throughout dispatch process for route matching.
Method Detection Logic
- CLI: php_sapi_name() === 'cli' sets method to 'CLI'
- HTTP: Uses $_SERVER['REQUEST_METHOD'] with HEAD treated as GET
- Fallback: Defaults to 'GET' if REQUEST_METHOD unavailable
Current request method ('GET', 'POST', 'PUT', 'DELETE', 'CLI')
Tags
$page404
Custom 404 handler callback for unmatched routes
private
static callable|null
$page404
= null
Optional callable that handles requests when no registered route matches the current path and method combination. If not set, router provides default 404 behavior with appropriate HTTP status codes or CLI messages.
Default 404 Behavior
- HTTP: Sets 404 status code and outputs "404 Not Found"
- CLI: Outputs simple "404 Not Found" message
- Events: Fires router.404 or router.404.no_callback events
Custom Handler Usage
Handler receives no parameters and should manage complete response including HTTP status codes, headers, and output content as needed.
Custom 404 handler, or null for default behavior
Tags
$path
Normalized request path used for route pattern matching
private
static string
$path
Contains the cleaned and normalized path extracted from either HTTP query parameters or CLI arguments. Normalized to ensure consistent slash handling and format across different input sources and contexts.
Path Sources
- HTTP: Extracted from $_GET['rt'] parameter and normalized
- CLI: Taken from first CLI argument ($argv[1]) and normalized
- Fallback: Defaults to '/' if no path provided
Normalization Rules
- HTTP: Ensures leading slash, removes trailing slashes, collapses multiple slashes
- CLI: Removes leading slashes and whitespace for command-style routing
Normalized request path for pattern matching
Tags
$routes
Master registry of all registered routes organized by HTTP method and CLI
private
static array<string, array<string, array{original: string, params: string[], middleware: string[], callback: callable}>>
$routes
= []
Multi-dimensional array storing route patterns, parameters, middleware, and callbacks organized by request method. Each method contains regex patterns as keys with associated route data including original pattern, parameter names, middleware chain, and handler callback.
Array Structure
[
'GET' => [
'#^/users/([^/]+)$#' => [
'original' => '/users/{id}',
'params' => ['id'],
'middleware' => [AuthMiddleware::class],
'callback' => $closure
]
],
'POST' => [...],
'CLI' => [...]
]
Tags
Methods
__wakeup()
Prevent unserialization of Router class
public
__wakeup() : mixed
Public wakeup method prevents object restoration from serialized state to maintain static-only usage pattern and global state integrity.
Tags
cli()
Register CLI command route with middleware pipeline and handler callback
public
static cli(string $route, array<string|int, string> $middleware, callable $callback) : void
Registers command-line interface routes for console applications, background jobs, maintenance tasks, and administrative operations. CLI routes receive command arguments and support middleware for authentication and validation.
CLI Route Features
- Command parsing: First argument used as route, additional args passed to handler
- Parameter extraction: Named parameters work like HTTP routes
- Argument passing: CLI arguments merged with extracted parameters
- Output handling: Direct console output, no HTTP concerns
- Error handling: Exit codes and error messaging
CLI vs HTTP Differences
- Context: Console execution vs web request
- Arguments: $argv array vs HTTP parameters
- Output: Direct echo/print vs HTTP responses
- Redirects: Console messages vs HTTP Location headers
- Status: Exit codes vs HTTP status codes
Argument Handling
CLI handler receives extracted route parameters first, followed by remaining command-line arguments as additional parameters using PHP's variadic syntax.
Parameters
- $route : string
-
Command pattern with optional named parameters (e.g.,
migrate
,user/create/{name}
) - $middleware : array<string|int, string>
-
Array of middleware class names for validation/auth
- $callback : callable
-
Command handler receiving parameters and additional CLI args
Tags
delete()
Register DELETE route with middleware pipeline and handler callback
public
static delete(string $route, array<string|int, string> $middleware, callable $callback) : void
Registers HTTP DELETE routes for resource removal following RESTful conventions. DELETE operations should be idempotent, safely removable multiple times without additional side effects once resource is gone.
RESTful DELETE Usage
- Resource removal: Permanent or soft deletion of resources
- Idempotent operations: Safe to repeat, no additional effects after first deletion
- Status consistency: 404 after deletion is acceptable behavior
- Cascade handling: Related resource cleanup and relationship management
- Authorization critical: Require strong authentication/authorization
Deletion Strategies
- Hard delete: Permanent removal from database
- Soft delete: Mark as deleted, preserve data for recovery
- Archive: Move to archive storage before removal
- Cascade: Handle dependent resource cleanup
Parameters
- $route : string
-
URI pattern typically including resource ID (e.g.,
/users/{id}
) - $middleware : array<string|int, string>
-
Array of middleware class names, typically including auth
- $callback : callable
-
Route handler receiving extracted parameters as arguments
Tags
dispatch()
Process current request by matching routes, executing middleware, and calling handlers
public
static dispatch() : void
Core routing engine that matches the current request against registered routes, executes middleware pipeline, and invokes route handlers. Handles both HTTP and CLI contexts with appropriate parameter passing and error responses.
Route Matching Process
- Method filtering: Only check routes registered for current HTTP method or CLI
- Pattern matching: Use regex patterns to match current path
- Parameter extraction: Extract named parameters from matched patterns
- Middleware execution: Run middleware chain in registration order
- Handler invocation: Call route callback with extracted parameters
Middleware Pipeline Execution
Each middleware receives context information and can:
- Continue: Return null/false to proceed to next middleware
- Redirect: Return string URL to trigger immediate redirect
- Error: Return array with 'error' key to halt with HTTP status code
- Halt: Exit or throw to completely stop processing
Middleware Method Signature
All middleware classes must implement:
public function handle(string $method, string $path, string $originalRoute, array $namedParams)
Middleware Return Value Handling
- null/false: Continue to next middleware in chain
- string (non-empty): Immediate redirect to specified URL
- array with 'error' key: HTTP status code, optional 'message' key
- Exception/exit: Complete request termination
Parameter Passing Logic
- HTTP routes: Parameters passed as individual arguments to callback
- CLI routes: Route parameters + remaining CLI arguments passed to callback
- Parameter order: Route parameters first, CLI args appended for CLI routes
- Type safety: All parameters passed as string values
Error Handling
- Middleware errors: HTTP status codes and error messages
- Middleware redirects: Location headers (HTTP) or console messages (CLI)
- No route match: Custom 404 handler or default "404 Not Found" response
- Exception safety: Middleware exceptions handled gracefully
Event Integration
Comprehensive event system for monitoring and debugging:
- Route matching and parameter extraction
- Middleware execution before/after with results
- Redirect and error handling
- 404 scenarios with callback information
Tags
Return values
void —Method handles complete request/response cycle
get()
Register GET route with middleware pipeline and handler callback
public
static get(string $route, array<string|int, string> $middleware, callable $callback) : void
Registers HTTP GET routes for read operations following RESTful conventions. GET routes should be safe and idempotent, suitable for data retrieval without side effects. Supports named parameters and middleware chain execution.
RESTful GET Usage
- Resource retrieval: Reading data without modification
- Safe operations: No server state changes
- Idempotent: Multiple identical requests produce same result
- Cacheable: Results can be cached by browsers/proxies
Parameter Extraction
Route patterns support named parameters using {name} syntax:
- Pattern:
/users/{id}
matches/users/123
- Extracted:
$id = '123'
passed to callback - Multiple parameters:
/posts/{id}/comments/{comment_id}
Parameters
- $route : string
-
URI pattern with optional named parameters (e.g.,
/users/{id}
) - $middleware : array<string|int, string>
-
Array of middleware class names to execute before callback
- $callback : callable
-
Route handler receiving extracted parameters as arguments
Tags
init()
Initialize routing engine by detecting execution context and extracting request details
public
static init() : void
Performs environment detection to determine whether execution is CLI or HTTP context, then extracts and normalizes the request method and path accordingly. Must be called before route registration or dispatch to establish proper routing context.
Context Detection Logic
- CLI Detection: Uses php_sapi_name() === 'cli' to identify command-line execution
- HTTP Detection: All other SAPI modes treated as HTTP requests
- Method Extraction: Gets REQUEST_METHOD from $_SERVER with fallbacks
- Path Extraction: Uses $_GET['rt'] for HTTP, $argv[1] for CLI
HTTP Context Handling
- Method: $_SERVER['REQUEST_METHOD'] or 'GET' as fallback
- HEAD requests: Automatically converted to GET for simplified handling
- Path: Extracted from $_GET['rt'] query parameter, normalized for consistency
- Default path: '/' when no route parameter provided
CLI Context Handling
- Method: Always set to 'CLI' for command-line routing
- Path: First command argument ($argv[1]), normalized for commands
- Default command: '/' when no command argument provided
- Arguments: Additional $argv elements available during dispatch
Event Integration
Fires 'router.init' event with normalized path and detected method for monitoring, logging, and debugging routing initialization.
Tags
listRoutes()
Retrieve complete list of registered routes with metadata
public
static listRoutes() : array<string|int, array{method: string, route: string, middleware: string[]}>
Returns comprehensive array of all registered routes across all HTTP methods and CLI commands. Includes original route patterns, middleware class names, and method information for debugging, documentation, and administrative purposes.
Return Data Structure
Each route entry contains:
- method: HTTP method (GET, POST, etc.) or 'CLI'
- route: Original route pattern with named parameters
- middleware: Array of middleware class names (strings)
Middleware Representation
Middleware entries are converted to class names for consistent representation:
- String middleware: Used as-is (typical case)
- Object middleware: Class name extracted via get_class()
- Empty middleware: Represented as empty array
Use Cases
- Documentation generation: API documentation from route definitions
- Administrative panels: Route management interfaces
- Debugging tools: Development route inspection
- Security audits: Middleware and route analysis
- Testing: Route registration verification
Tags
Return values
array<string|int, array{method: string, route: string, middleware: string[]}> —Complete route registry
page404()
Set custom 404 handler for unmatched routes
public
static page404(callable $callback) : void
Registers a custom callback to handle requests that don't match any registered routes. Handler should manage complete response including HTTP status codes, headers, and output content for both HTTP and CLI contexts.
Handler Responsibilities
- HTTP context: Set appropriate status code (typically 404)
- Response headers: Content-Type and other relevant headers
- Output content: Error pages, JSON responses, or redirect logic
- CLI context: Console-appropriate error messages
- Logging: Optional error logging or monitoring integration
Default 404 Behavior
When no custom handler is registered:
- HTTP: Sets 404 status code and outputs "404 Not Found"
- CLI: Outputs "404 Not Found" to console
- Events: Fires router.404.no_callback event for monitoring
Handler Parameters
The 404 handler receives no parameters and should determine context and response format based on environment or global state.
Parameters
- $callback : callable
-
404 handler receiving no parameters
Tags
post()
Register POST route with middleware pipeline and handler callback
public
static post(string $route, array<string|int, string> $middleware, callable $callback) : void
Registers HTTP POST routes for resource creation and non-idempotent operations. POST routes typically create new resources, process form submissions, or perform operations with side effects. Supports request body parsing and parameter extraction.
RESTful POST Usage
- Resource creation: Creating new database records
- Form processing: Handling form submissions with validation
- Non-idempotent: Multiple requests may create multiple resources
- Data modification: Operations that change server state
- File uploads: Multipart form data processing
Request Data Access
POST data available through Params class after initialization:
- Form data: Params::post() for form-encoded submissions
- JSON data: Params::json() for JSON request bodies
- File uploads: Params::files() for multipart submissions
Parameters
- $route : string
-
URI pattern with optional named parameters (e.g.,
/users
) - $middleware : array<string|int, string>
-
Array of middleware class names for validation/auth
- $callback : callable
-
Route handler receiving extracted parameters as arguments
Tags
printRouteList()
Output HTML table of registered routes for browser-based debugging
public
static printRouteList() : void
Generates formatted HTML table displaying all registered routes with styling for easy visual inspection during development. Includes color-coded HTTP methods and proper escaping for safe browser display.
HTML Output Features
- Styled table: CSS styling with borders, padding, and typography
- Color-coded methods: Visual distinction between HTTP methods
- Responsive design: Table adapts to different screen sizes
- Safe output: HTML escaping prevents XSS from route patterns
- Empty state: Special message when no routes registered
Method Color Coding
- GET: Green (safe, read-only operations)
- POST: Orange (creation, form submission)
- PUT/PATCH: Teal (updates, modifications)
- DELETE: Red (destructive operations)
- CLI: Default styling for command-line routes
Development Usage
Primarily intended for development and debugging scenarios where visual route inspection aids in understanding application structure and middleware configuration.
Tags
Return values
void —Outputs HTML directly to browser
put()
Register PUT route with middleware pipeline and handler callback
public
static put(string $route, array<string|int, string> $middleware, callable $callback) : void
Registers HTTP PUT routes for complete resource replacement following RESTful conventions. PUT operations should be idempotent, replacing entire resources with provided data rather than partial updates.
RESTful PUT Usage
- Resource replacement: Complete resource update/replacement
- Idempotent operations: Same result when repeated multiple times
- Full data required: Entire resource representation expected
- Create or update: Can create resource if it doesn't exist
- Atomic operations: Complete success or failure
PUT vs PATCH Distinction
- PUT: Replace entire resource with provided representation
- PATCH: Partial updates to specific resource fields
- PUT idempotency: Multiple identical PUT requests yield same result
- PUT completeness: All resource fields should be provided
Parameters
- $route : string
-
URI pattern typically including resource ID (e.g.,
/users/{id}
) - $middleware : array<string|int, string>
-
Array of middleware class names for auth/validation
- $callback : callable
-
Route handler receiving extracted parameters as arguments
Tags
__clone()
Prevent cloning of Router class
private
__clone() : mixed
Private clone method prevents object cloning to maintain singleton-like behavior and ensure single global routing state throughout application.
Tags
__construct()
Prevent instantiation of Router class
private
__construct() : mixed
Private constructor enforces static-only usage pattern by preventing object creation. Router is designed as a static utility class with global state management for routing operations.
Tags
addRoute()
Internal route registration with pattern conversion and data storage
private
static addRoute(string $method, string $route, array<string|int, string> $middleware, callable $callback) : void
Core route registration method that converts route patterns to regex, extracts parameter names, and stores complete route data in the routes registry. Used by all public route registration methods.
Registration Process
- Pattern conversion: Convert route pattern to regex via routeToRegex()
- Parameter extraction: Extract named parameter list from pattern
- Data structure: Build complete route data array
- Registry storage: Store under method and regex pattern keys
Route Data Structure
Each registered route contains:
- original: Original route pattern for documentation/debugging
- params: Array of parameter names for extraction
- middleware: Middleware class array for execution pipeline
- callback: Handler callable for route execution
Registry Organization
Routes organized by method, then by regex pattern for efficient matching:
$routes[$method][$regexPattern] = $routeData
Parameters
- $method : string
-
HTTP method (GET, POST, etc.) or 'CLI'
- $route : string
-
Original route pattern with named parameters
- $middleware : array<string|int, string>
-
Array of middleware class names
- $callback : callable
-
Route handler callback
Tags
normalizeCliRoute()
Normalize CLI command routes by removing slashes and whitespace
private
static normalizeCliRoute(string $cmd) : string
Cleans command-line route patterns to remove web-style slashes and whitespace, making CLI commands more natural while maintaining compatibility with web-style route patterns.
CLI Normalization Rules
- Whitespace removal: Trim leading/trailing whitespace
- Leading slash removal: Remove leading slashes for command style
- Command format: Results in command/subcommand format
- Empty handling: Preserves empty string for default command
Command Style Compatibility
Accepts both web-style (/migrate/up
) and command-style (migrate/up
)
patterns, normalizing to command-style for consistent CLI experience.
Input/Output Examples
'/migrate'
→'migrate'
(remove leading slash)' /user/create '
→'user/create'
(trim and remove slash)'cache/clear'
→'cache/clear'
(already normalized)' '
→''
(whitespace becomes empty)
Parameters
- $cmd : string
-
Command string from CLI arguments
Tags
Return values
string —Normalized CLI route without leading slashes or whitespace
normalizeRoute()
Normalize HTTP routes by standardizing slash handling and format
private
static normalizeRoute(string $rt) : string
Cleans and standardizes HTTP route paths to ensure consistent matching regardless of input format variations. Handles multiple slashes, trailing slashes, and empty paths with consistent rules.
Normalization Rules
- Multiple slashes: Collapse multiple consecutive slashes to single slash
- Trailing slash removal: Remove trailing slashes except for root
- Leading slash: Ensure leading slash for all non-empty paths
- Empty path handling: Convert empty string to root path '/'
- Root preservation: Root path '/' remains unchanged
Input/Output Examples
''
→'/'
(empty becomes root)'users'
→'/users'
(add leading slash)'/users/'
→'/users'
(remove trailing slash)'//users//profile/'
→'/users/profile'
(clean multiple slashes)'/'
→'/'
(root unchanged)
Parameters
- $rt : string
-
Route string from query parameter or path
Tags
Return values
string —Normalized route string with consistent format
routeToRegex()
Convert route pattern to regex and extract parameter names
private
static routeToRegex(string $route) : array{0: string, 1: string[]}
Transforms human-readable route patterns with named parameters into regex patterns suitable for URL matching, while extracting parameter names for value extraction during dispatch.
Pattern Conversion Process
- Normalization: Clean multiple slashes to single slashes
- Parameter detection: Find all {paramName} segments
- Parameter extraction: Extract parameter names for later use
- Regex creation: Replace parameters with capture groups
- Anchoring: Add start/end anchors for exact matching
Parameter Name Rules
- Format: Must match
{[a-zA-Z_][a-zA-Z0-9_]*}
pattern - Starting character: Letter or underscore only
- Subsequent characters: Letters, numbers, underscores
- Case sensitive: Parameter names preserved exactly
Regex Pattern Generation
- Parameter replacement:
{param}
becomes([^/]+)
(capture non-slash) - Exact matching: Anchored with
^
and$
- Delimiter handling: Uses
#
as delimiter to avoid conflicts
Parameters
- $route : string
-
Route pattern with optional named parameters
Tags
Return values
array{0: string, 1: string[]} —[regex pattern, parameter names array]