<?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();
    }
}

final class QueryMiddleware extends MiddlewareWorker
{
    public function path(string $path, callable $callback)
    {
        $this->module(function ($middleware, $arguments, $next) use ($callback, $path): mixed
        {
            return $path === $arguments[0]
                ? call_user_func($callback, $middleware, $arguments, $next)
                : $next($arguments);
        });
    }
}

(function ()
{
    $middleware = new QueryMiddleware();
    
    # authorization
    $middleware->module(function ($middleware, $arguments, $next): string
    {
        return '{"type":"access","data":' . $next($arguments) . '}';
    });
    
    $middleware->path('/processes', function ()
    {
        echo 'processes' . PHP_EOL;
        return '[]';
    });
    
    echo $middleware->run('/processes');
})();

Embed on website

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