CodeBlanks Logo Icon CodeBlanks

Summary - Middleware

PHP course · Advanced · Lesson 73/92

Build a protected API route structure with auth, logging and PSR-15.

Summary - Middleware

In this group you learned the middleware pattern, the before/after idea, building a pipeline with array_reduce, auth and logging layers, and the PSR-15 interface.

Now combine them: chain auth and logging middlewares with buildPipeline and observe different outputs for guest and member requests. Then write a PSR-15 style ErrorHandler class that catches exceptions and returns a clean response.

These two tasks give you practice using both callable and class based middleware in the same project.

Exercise Auth + logging pipeline

Define three functions: authMiddleware, loggingMiddleware and buildPipeline. authMiddleware returns "unauthorized" when $_SESSION['user_id'] is missing (early return); otherwise it returns $next($request). loggingMiddleware prints "[LOG] {$request}" and returns $next($request). buildPipeline uses array_reduce and array_reverse to produce a wrapping callable. Build the pipeline and call it twice: first as guest, then as a member; print the results.

Show example solution
Write function authMiddleware($request, $next) { if (!isset($_SESSION['user_id'])) { return "unauthorized"; } return $next($request); } and function loggingMiddleware($request, $next) { echo "[LOG] {$request}\n"; return $next($request); }. Reuse buildPipeline from the previous lesson. Then $pipeline = buildPipeline(['loggingMiddleware', 'authMiddleware'], $finalHandler); unset($_SESSION['user_id']); echo $pipeline("panel") . "\n"; $_SESSION['user_id'] = 42; echo $pipeline("panel") . "\n";.
Example solution:
<?php
function authMiddleware($request, $next) {
    if (!isset($_SESSION['user_id'])) {
        return "unauthorized";
    }
    return $next($request);
}
function loggingMiddleware($request, $next) {
    echo "[LOG] {$request}\n";
    return $next($request);
}
function buildPipeline(array $middlewares, callable $handler): callable {
    return array_reduce(array_reverse($middlewares), function ($next, $mw) {
        return function ($request) use ($mw, $next) {
            return $mw($request, $next);
        };
    }, $handler);
}
session_start();
$finalHandler = function ($request) {
    return "DONE";
};
$pipeline = buildPipeline(['loggingMiddleware', 'authMiddleware'], $finalHandler);
unset($_SESSION['user_id']);
echo $pipeline("panel") . "\n";
$_SESSION['user_id'] = 42;
echo $pipeline("panel") . "\n";

Exercise A PSR-15 style ErrorHandler

Define an ErrorHandler class that mimics the PSR-15 structure. Give it a public function process($request, $handler) method. Inside, wrap try { return $handler->handle($request); } with a catch (\Exception $e); on error return "ERROR: " . $e->getMessage(). FinalHandler and CrashHandler are already defined. Instantiate the ErrorHandler, call process with both handlers and print the results.

Show example solution
" . $e->getMessage(); } } }. Then $eh = new ErrorHandler(); echo $eh->process("istek", new FinalHandler()) . "\n"; echo $eh->process("istek", new CrashHandler()) . "\n";.
Example solution:
<?php
class ErrorHandler {
    public function process($request, $handler) {
        try {
            return $handler->handle($request);
        } catch (\Exception $e) {
            return "ERROR: " . $e->getMessage();
        }
    }
}
class FinalHandler {
    public function handle($request) {
        return "DONE";
    }
}
class CrashHandler {
    public function handle($request) {
        throw new \Exception("server error");
    }
}
$eh = new ErrorHandler();
echo $eh->process("istek", new FinalHandler()) . "\n";
echo $eh->process("istek", new CrashHandler()) . "\n";

Test yourself

  1. Match all the middleware concepts

    $next
    Moves to the next step
    array_reduce
    Builds the pipeline
    Auth
    Verifies the session
    PSR-15
    Standard interface
  2. When does the first middleware in a pipeline run?

    • Never
    • Last, when the response returns
    • First, as the outer layer
    • Only on errors
    Show answer

    First, as the outer layer — Correct. The first middleware is the outer layer; its before runs first.

All lessons in Advanced