Выход Laravel 11 намечен на первый квартал 2024-го года, что может произойти уже в следующем месяце.

Я начинаю новый проект, и поскольку дата выхода очень близка, решил взглянуть на то что изменится в новом крупном обновлении. Помню как пол года назад прочитал в Laravel News статью о том, что Http Kernel уходит в небытие, и не придал этому особого значения.

Когда я создал проект с помощью команды laravel new project --dev, я был очень удивлён тем, насколько уменьшился размер проекта. Было очень удивительно видеть пустую папку config (можно опубликовать файлы конфигурации при помощи команды php artisan config:publish)!

И, конечно же, там нет Http Kernel. Итак... как же добавить или изменить мидлвари? До Laravel 11 ядро Http Kernel, располагающееся по пути app/Http/Kernel.php,было местом хранения всей конфигурации для мидлварей. Также до Laravel 11 не было необходимости трогать руками файл bootstrap/app.php, если только Вы не использовали фреймворк Lumen. Однако в новой версии его нужно будет трогать.

Честно говоря, для меня, как пользователя Laravel начиная с версии 4.2, это просто смена парадигмы. Вместо легко читаемого файла Kernel.php появилось гораздо больше неявных знаний, необходимых перед добавлением мидлварей.

Новый начальный файл bootstrap/app.php выглядит следующим образом:

return Application::configure()
    ->withProviders()
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        // api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        // channels: __DIR__.'/../routes/channels.php',
    )
    ->withMiddleware(function (Middleware $middleware) {
        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

В этом посте я просто исследую мидлвари, но, как Вы видите, это совершенно иной подход нежели тот, который мы видели раньше. Я сидел и ломал голову как мне настроить собственные мидлвари? Как изменить настройки по-умолчанию? Чтобы узнать это, мне пришлось изучить файл Illuminate\Foundation\Configuration\Middleware.

Вызов Application::configure() возвращает экземпляр Illuminate\Foundation\Configuration\ApplicationBuilder, где впоследствии вызываются withProviders(), withRouting(), withMiddleware() и другие функции. Функция withMiddleware() принимает вызываемый объект (callable).

Используя шаблон, мы можем добавить новые алиасы для мидлварей, вызвав alias():

function (Middleware $middleware) {
    $middleware->alias([
        'some_key' => \App\Http\Middleware\MyMiddleware::class,
    ]);
}

После добавления some_key, мы можем назначить его как отдельным маршрутам, так и их группам. Если мы хотим добавлять мидлвари в каждый запрос, можно использовать функции append() и prepend() для добавления глобальных мидлварей.

function (Middleware $middleware) {
    // Using a string
    $middleware->append(\App\Http\Middleware\MyMiddleware::class);

    // Or adding multiple
    $middleware->append([
        \App\Http\Middleware\MyMiddleware::class,
        \App\Http\Middleware\MyOtherMiddleware::class,
    ]);
}

Мы можем удалить дефолтные мидлвари, вызвав функцию remove():

function (Middleware $middleware) {
    // Using a string
    $middleware->remove(\Illuminate\Http\Middleware\ValidatePostSize::class);

    // Or removing multiple default middleware
    $middleware->remove([
        \Illuminate\Http\Middleware\TrustProxies::class,
        \Illuminate\Http\Middleware\HandleCors::class,
    ]);
}

Мы можем добавлять или удалять мидлвари в определённых группах, например, в web, используя функции appendToGroup(), prependToGroup() и removeFromGroup():

function (Middleware $middleware) {
    $middleware->appendToGroup('web', \App\Http\Middleware\MyMiddleware::class);
}

Если/когда файл bootstrap/app.php превратится в помойку (а это несомненно произойдёт), мы можем навести порядок, переместив всё это дело в вызываемый класс.

Я создал класс в app/Http под названием AppMiddleware.php. Поскольку старые привычки умирают медленно, Вы можете назвать его Kernel.php.

<?php

namespace App\Http;

use Illuminate\Foundation\Configuration\Middleware;

class AppMiddleware
{
    public function __invoke(Middleware $middleware)
    {
        $middleware->appendToGroup('web', \App\Http\Middleware\MyMiddleware::class);
    }
}

Теперь в файле bootstrap/app.php нужно заменить замыкание на созданный экземпляр класса:

return Application::configure()
    ->withProviders()
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        // api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        // channels: __DIR__.'/../routes/channels.php',
    )
    ->withMiddleware(new \App\Http\AppMiddleware()) // here
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

Как и всё новое, перемены даются тяжело. В связи с этим меня мучает один вопрос. У нас есть всё те же инструменты и возможности, но понять как всем этим управлять, немного сложнее, по крайней мере, на первых порах.

Мне кажется, что это изменение потребует гораздо больше неявных познаний о работе мидлварей. Имеет ли это значение? Скорее всего нет. Но в некоторых случаях Вам может понадобиться удалить или заменить дефолтные значения. Это потребует от Вас знания того, что есть по-умолчанию. Не только в глобальных мидлварях, но и в группах, а также под алиасами. Лично мне кажется, что это изменение увеличивает кривую обучения. Даже я забываю что там есть по-дефолту или какие существуют псевдонимы, и регулярно проверяю файл app/Http/Kernel.php.

Я сомневаюсь стоит ли оно того. А что Вы думаете об этом?

Комментарии (3)


  1. AleksandrTm
    09.01.2024 13:28
    +3

    " Это потребует от Вас знания того, что есть по-умолчанию. "

    Интересно, не будет ли расширен список artisan команд в таком случае

    artisan middleware:list


    1. Helldar Автор
      09.01.2024 13:28

      Скорее всего будет, т.к. ни для кого не секрет что Тейлор идёт на поводу общества и когда народ массово начнёт его спрашивать о том как посмотреть список, он добавит эту команду.

      Также как если попытаться её добавить до того как народ обратит внимание, ответит дефолтным сообщением "пиши пакет" и закроет PR ????


  1. firdavsBEK
    09.01.2024 13:28
    +1

    Это по моему типа слияние люмена и ларавеля, то есть если хотим апи, тогда не нужные мидлвари не будут загружаться, то есть web часть не будет работать