Rudra FrameworkRudra Framework

Middleware

Middleware в Rudra — это перехватчики запроса и ответа, которые позволяют выполнять логику до или после вызова действия контроллера.


Как объявить middleware

✅Middleware подключается к методу контроллера через атрибуты:

#[Middleware(name: 'App\Containers\Demo\Middleware\FirstMiddleware')]
#[AfterMiddleware(name: 'App\Containers\Demo\Middleware\SecondMiddleware')]
public function attributes(stdClass $std, string $name = 'John'): void
{
    // тело действия
}
  • #[Middleware] — выполняется до метода.
  • #[AfterMiddleware] — выполняется после метода.

⚠️ Порядок важен: middleware выполняются в том порядке, в котором указаны.

Как создать middleware

Middleware — это любой класс с методом __invoke($next, ...$params):

<?php // App/Containers/Admin/Middleware/UnsetSessionMiddleware.php

namespace App\Containers\Admin\Middleware;

use Rudra\Container\Facades\Session;

class UnsetSessionMiddleware
{
    public function __invoke($next, ...$params)
    {
        // Логика до вызова контроллера
        Session::remove('value');
        Session::remove('alert');
        Session::remove('errors');

        // Обязательный вызов следующего middleware или контроллера
        if ($next) {
            $next();
        }

        // Логика после (если нужно) — но обычно используется AfterMiddleware
    }
}

⚠️Важно: вызов $next() обязателен, иначе цепочка прервётся, и контроллер не выполнится.


Когда использовать?

  • Before-middleware: аутентификация, валидация, логирование запроса, очистка сессии.
  • After-middleware: логирование ответа, модификация заголовков, отправка уведомлений.

Особенности

  • Middleware не создаётся через DI автоматически — он вызывается по имени класса.
  • Если middleware зависит от сервисов, внедрите их вручную внутри __invoke через Rudra::get() — или зарегистрируйте middleware как сервис в config.php.

Пример с DI:

public function __invoke($next, ...$params)
{
    $logger = Rudra::get(Logger::class);
    $logger->info('Request started');
   
    if ($next) $next();
}

Регистрация middleware через фасад Router

ℹ️Когда маршруты объявляются вручную (например, в файле routes.php), middleware можно указать напрямую в опциях маршрута.

Через методы get, post, put и т.д.

use Rudra\Router\RouterFacade as Router;
use App\Containers\Web\Controller\IndexController;
use App\Containers\Web\Middleware\BeforeMiddleware;
use App\Containers\Web\Middleware\AfterMiddleware;


Router::get('web/index', [IndexController::class, 'actionIndex'], [
    'before' => [BeforeMiddleware::class],
    'after'  => [AfterMiddleware::class]
]);

✅Поддерживается любое количество middleware. Порядок выполнения — слева направо.

Через универсальный метод set

Router::set([
    'url'        => 'web/index',
    'method'     => 'GET',
    'controller' => IndexController::class,
    'action'     => 'actionIndex',
    'middleware' => [
        'before' => [BeforeMiddleware::class],
        'after'  => [AfterMiddleware::class]
    ]
]);

Этот синтаксис удобен, если маршрут настраивается динамически или из конфигурации.


Важно

  • Middleware, указанные через фасад, работают так же, как и через атрибуты #[Middleware].
  • Классы middleware должны быть доступны через автозагрузку (PSR-4).
  • Вызов $next() внутри __invoke() — обязателен, иначе контроллер не выполнится.