CodeBlanks Logo Icon CodeBlanks

Middleware chain

PHP course · Advanced · Lesson 69/92

Learn to chain multiple middlewares with arrays and callables.

The middleware chain

Instead of one middleware, you often run a list of middlewares in sequence. Each hands off to the next with $next; the real handler at the end produces the response.

This structure is a pipeline. With array_reduce you can fold the middleware array into a single callable. Each step produces a new closure that wraps the $next it received.

Order matters: the first middleware becomes the outer layer, so its before runs first and its after runs last. That is why you reverse the array with array_reverse before folding.

Pipeline with array_reduce

buildPipeline works like this: array_reduce walks the reversed middleware array. The initial value is the innermost handler. At each step a new closure is returned that wraps $mw and $next.

The wrapper closure: function ($request) use ($mw, $next) { return $mw($request, $next); }. So from outside in, each middleware wraps the call after it.

The reversal is needed because array_reduce goes left to right; the first middleware must be the outer layer. Without reversal the order would be inverted.

Exercise Write the buildPipeline function

Define a buildPipeline(array $middlewares, callable $handler): callable function. Use array_reduce to walk array_reverse($middlewares); at each step return a closure that wraps $mw and $next. $finalHandler and $middlewares are already defined. Build the pipeline, call it with "istek" and print the result.

Show example solution
callable { return array_reduce(array_reverse($middlewares), function ($next, $mw) { return function ($request) use ($mw, $next) { return $mw($request, $next); }; }, $handler); }. Then $pipeline = buildPipeline($middlewares, $finalHandler); echo $pipeline("istek") . "\n";.
Example solution:
<?php
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);
}
$finalHandler = function ($request) {
    return "TAMAM";
};
$middlewares = [
    function ($request, $next) {
        echo "A-before\n";
        $r = $next($request);
        echo "A-after\n";
        return $r;
    },
    function ($request, $next) {
        echo "B-before\n";
        $r = $next($request);
        echo "B-after\n";
        return $r;
    },
];
$pipeline = buildPipeline($middlewares, $finalHandler);
echo $pipeline("istek") . "\n";

Test yourself

  1. The pipeline builder call

    $pipeline = ____($middlewares, $handler);
    Show answer
    $pipeline = buildPipeline($middlewares, $handler);
  2. Why is the array reversed when building a pipeline with array_reduce?

    • To sort the array alphabetically
    • To make it run faster
    • So the first middleware becomes the outer layer
    • To save memory
    Show answer

    So the first middleware becomes the outer layer — Correct. array_reduce goes left to right; reversing puts the first middleware outermost.

  3. Match the pipeline tools

    array_reduce
    Folds the array into one value
    array_reverse
    Reverses the array order
    callable
    Invocable function
    Closure
    Anonymous function

All lessons in Advanced