Middleware

Strata v1.0.0 uses a simple closure pattern. Wrap route handlers to run code before or after them.

Note: PSR-15 middleware stack is planned for v2.0. v1.0.0 uses manual wrapping. No global middleware registry.

Route Middleware

Wrap your handler in a function to check auth, set headers, etc:

<?php
use App\Router;

$router = new Router();

// Middleware function returns a wrapped handler
function requireAuth($handler) {
    return function() use ($handler) {
        if (!isset($_SESSION[$sessionPrefix . 'user_id'])) {
            http_response_code(401);
            return 'Unauthorized';
        }
        return $handler(); // Continue to route
    };
}

// Apply to a route
$router->get('/admin', requireAuth(function() {
    return 'Dashboard';
}));

$router->run();

Chaining Multiple

Nest functions to run multiple checks:

function startSession($handler) {
    return function() use ($handler) {
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
        return $handler();
    };
}

function requireAdmin($handler) {
    return function() use ($handler) {
        if (($_SESSION[$sessionPrefix . 'role'] ?? null) !== 'admin') {
            http_response_code(403);
            return 'Forbidden';
        }
        return $handler();
    };
}

// Runs startSession → requireAuth → requireAdmin → handler
$router->get('/admin/users', 
    startSession(
        requireAuth(
            requireAdmin(
                function() {
                    return 'User List';
                }
            )
        )
    )
);

Common Patterns

Pattern What it does
Auth check Check $_SESSION[$sesionPrefix . 'user_id'], return 401 if missing
CSRF check Validate POST token against session
CORS headers Set Access-Control-Allow-Origin before handler runs
Rate limit Check request count in session/DB, return 429 if exceeded

Example: CORS Middleware

function cors($handler) {
    return function() use ($handler) {
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
        
        if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
            http_response_code(204);
            return '';
        }
        
        return $handler();
    };
}

$router->get('/api/data', cors(function() {
    return json_encode(['data' => 'value']);
}));

Global Code

For code that runs on every request, put it in public/index.php before $router->run():

<?php
require __DIR__ . '/../vendor/autoload.php';

use App\Router;

// Runs on every request
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

header('X-Powered-By: StrataPHP');

$router = new Router();
// ... routes ...

$router->run();