<?php

class MiddlewareWorker
{
    private $modules;
    
    private function callback(): callable
    {
        $next = function ()
        {
            throw new Exception('Базовая функция не может быть вызвана');
        };
        
        foreach (array_reverse($this->modules) as $callback)
        {
            $next = fn (array $arguments): mixed => call_user_func($callback, $this, $arguments, $next);
        }
        
        return $next;
    }
    
    public function run(...$arguments): mixed
    {
        $link = $this->callback();
        $data = $link($arguments);
        
        return $data;
    }
    
    public function module(callable $callback): void
    {
        $this->modules[] = $callback;
    }
    
    public function __construct()
    {
        $this->modules = array();
    }
}

(function ()
{
    $middleware = new MiddlewareWorker();
    
    $middleware->module(function ($link, $args, $next)
    {
        echo '#begin block 1' . PHP_EOL;
        echo '#print block 1 => ' . $next($args) . PHP_EOL;
        echo '#close block 1' . PHP_EOL;
        
        return '[block 1]';
    });
    
    $middleware->module(function ($link, $args, $next)
    {
        echo '#begin block 2' . PHP_EOL;
        echo '#print block 2 => ' . $next($args) . PHP_EOL;
        echo '#close block 2' . PHP_EOL;
        
        return '[block 2]';
    });
    
    $middleware->module(function ()
    {
        echo '#begin block 3' . PHP_EOL;
        echo '#close block 3' . PHP_EOL;
        
        return '[block 3]';
    });
    
    echo '#begin runner' . PHP_EOL;
    echo '#print runner => ' . $middleware->run() . PHP_EOL;
    echo '#close runner' . PHP_EOL;
})();

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: