Middleware
Middleware provides a convenient mechanism for filtering HTTP requests entering your application. Middleware in Sroute follows a Last-In-First-Out (LIFO) execution order.
Creating Middleware
Section titled “Creating Middleware”All middleware classes must implement the handle() method that accepts a callable $next parameter:
<?php
namespace Middleware;
class AuthMiddleware{ /** * Handle the incoming request. * * @param callable $next The next callable in the pipeline * @return void */ public function handle(callable $next) { // Check if user is authenticated if (!isset($_SESSION['user_id'])) { header('Location: /login'); exit; }
// Continue to next middleware or controller $next(); }}Registering Middleware Aliases
Section titled “Registering Middleware Aliases”Register middleware aliases in your bootstrap file to use short names in routes:
<?php
use Krag\Sroute\Router;use Middleware\AuthMiddleware;use Middleware\GuestMiddleware;use Middleware\CsrfMiddleware;
$router = new Router();
// Register middleware aliases$router->aliasMiddleware('auth', AuthMiddleware::class);$router->aliasMiddleware('guest', GuestMiddleware::class);$router->aliasMiddleware('csrf', CsrfMiddleware::class);Using Middleware on Routes
Section titled “Using Middleware on Routes”Attach middleware to routes using the middleware() method:
// Single middleware$router->get('/dashboard', DashboardController::class, 'index') ->middleware(['auth']);
// Multiple middleware$router->post('/login', AuthController::class, 'login') ->middleware(['csrf', 'guest']);Middleware Execution Order
Section titled “Middleware Execution Order”Middleware executes in LIFO (Last-In-First-Out) order. This means the last middleware added runs first.
$router->post('/checkout', CheckoutController::class, 'process') ->middleware(['csrf', 'auth']);Execution flow:
CsrfMiddlewareruns first (last in array)AuthMiddlewareruns second- Controller action runs last
Why LIFO?
Section titled “Why LIFO?”This allows you to wrap inner middleware with outer ones. For example, CSRF protection should verify the token before authentication checks run.
Example Middleware
Section titled “Example Middleware”Guest Middleware
Section titled “Guest Middleware”Redirect authenticated users away from login/register pages:
<?php
namespace Middleware;
class GuestMiddleware{ public function handle(callable $next) { if (isset($_SESSION['user_id'])) { header('Location: /dashboard'); exit; }
$next(); }}CSRF Middleware
Section titled “CSRF Middleware”Protect against Cross-Site Request Forgery:
<?php
namespace Middleware;
class CsrfMiddleware{ public function handle(callable $next) { $token = $_POST['csrf_token'] ?? ''; $sessionToken = $_SESSION['csrf_token'] ?? '';
if (!hash_equals($sessionToken, $token)) { http_response_code(403); echo 'CSRF token mismatch'; exit; }
$next(); }}Role-Based Middleware
Section titled “Role-Based Middleware”Check user permissions:
<?php
namespace Middleware;
class AdminMiddleware{ public function handle(callable $next) { $userRole = $_SESSION['user_role'] ?? null;
if ($userRole !== 'admin') { http_response_code(403); echo 'Access denied'; exit; }
$next(); }}Best Practices
Section titled “Best Practices”- Keep middleware focused: Each middleware should have a single responsibility
- Always call
$next(): Unless you want to terminate the request - Use early returns: Exit early for failed checks to avoid unnecessary processing
- Register aliases: Use short, descriptive names for middleware