Новая версия фреймворка Laravel 9 вышла 8 февраля 2022 года. Релиз включает в себя множество новых функций,  в том числе минимальную версию PHP v8.0.

Схема управления версиями

Laravel и другие его собственные пакеты следуют Semantic Versioning . Основные выпуски фреймворка выпускаются каждый год (~ февраль), в то время как второстепенные выпуски и выпуски исправлений могут выпускаться каждую неделю. Второстепенные выпуски и выпуски исправлений никогда не должны содержать критических изменений.

При ссылке на фреймворк Laravel или его компоненты из вашего приложения или пакета вы всегда должны использовать ограничение версии, такое как ^9.0, поскольку основные выпуски Laravel содержат критические изменения. Тем не менее, мы стремимся всегда гарантировать, что вы сможете выполнить обновление до новой основной версии за один день или меньше.

Именованные аргументы

Именованные аргументы не подпадают под действие рекомендаций Laravel по обратной совместимости. При необходимости мы можем переименовать аргументы функции, чтобы улучшить кодовую базу Laravel. Поэтому использовать именованные аргументы при вызове методов Laravel следует осторожно и с пониманием того, что имена параметров могут измениться в будущем.

Новые выпуски

Для всех выпусков Laravel исправления ошибок предоставляются на 18 месяцев, а исправления безопасности — на 2 года. Для всех дополнительных библиотек, включая Lumen, только последний выпуск получает исправления ошибок. Кроме того, проверьте версии баз данных, поддерживаемые Laravel .

 

Laravel 9 

Как вы, возможно, знаете, Laravel перешел на ежегодные выпуски с выпуском Laravel 8. Раньше основные версии выпускались каждые 6 месяцев. Этот переход предназначен для того, чтобы облегчить бремя обслуживания для сообщества и побудить нашу команду разработчиков выпускать потрясающие, мощные новые функции, не внося критических изменений. Поэтому мы добавили в Laravel 8 множество надежных функций без нарушения обратной совместимости, таких как поддержка параллельного тестирования, улучшенные стартовые наборы Breeze, улучшения HTTP-клиента и даже новые типы отношений Eloquent, такие как «имеет один из многих».

Поэтому это обязательство по выпуску замечательных новых функций в текущем выпуске, вероятно, приведет к тому, что будущие «основные» выпуски будут в основном использоваться для задач «обслуживания», таких как обновление вышестоящих зависимостей, что можно увидеть в этих примечаниях к выпуску.

Laravel 9 продолжает улучшения, сделанные в Laravel 8.x, путем введения поддержки компонентов Symfony 6.0, Symfony Mailer, Flysystem 3.0, улучшенного route:listвывода, драйвера базы данных Laravel Scout, нового синтаксиса доступа/мутатора Eloquent, неявных привязок маршрутов через Enums и различных других исправлений ошибок и улучшений удобства использования.

 

PHP 8.0

Для Laravel 9.x требуется минимальная версия PHP 8.0.

Symfony Mailer

Предыдущие выпуски Laravel использовали библиотеку Swift Mailer для отправки исходящей электронной почты. Однако эта библиотека больше не поддерживается, и ее заменил Symfony Mailer.

Flysystem 3.x

Laravel 9.x обновляет нашу исходную зависимость Flysystem до Flysystem 3.x. Flysystem поддерживает все взаимодействия с файловой системой, предлагаемые Storage фасадом.

Улучшенные Eloquent Accessors/Mutators

Laravel 9.x предлагает новый способ определения средств доступа и мутаторов Eloquent . В предыдущих выпусках Laravel единственным способом определения аксессоров и мутаторов было определение префиксных методов в вашей модели следующим образом:

public function getNameAttribute($value)
{
    return strtoupper($value);
}
 
public function setNameAttribute($value)
{
    $this->attributes['name'] = $value;
}

Однако в Laravel 9.x вы можете определить аксессор и мутатор, используя один метод без префикса, указывая тип возвращаемого типа Illuminate\Database\Eloquent\Casts\Attribute:

use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}

Кроме того, этот новый подход к определению методов доступа будет кэшировать значения объекта, возвращаемые атрибутом, точно так же, как пользовательские классы приведения :

use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function address(): Attribute
{
    return new Attribute(
        get: fn ($value, $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}

Enum Eloquent приведение атрибутов

Eloquent теперь позволяет вам приводить значения ваших атрибутов к перечислениям, поддерживаемым PHP . Для этого вы можете указать атрибут и перечисление, которое вы хотите указать в $castsмассиве свойств вашей модели:

use App\Enums\ServerStatus;
 
/**
 * The attributes that should be cast.
 *
 * @var array
 */
protected $casts = [
    'status' => ServerStatus::class,
];

После того, как вы определили приведение к своей модели, указанный атрибут будет автоматически преобразован в перечисление и из него при взаимодействии с атрибутом:

if ($server->status == ServerStatus::provisioned) {
    $server->status = ServerStatus::ready;
 
    $server->save();
}

Неявные привязки маршрутов с перечислениями

В PHP 8.1 появилась поддержка Enums . В Laravel 9.x появилась возможность указывать тип Enum в определении вашего маршрута, и Laravel будет вызывать маршрут только в том случае, если этот сегмент маршрута является допустимым значением Enum в URI. В противном случае ответ HTTP 404 будет возвращен автоматически. Например, учитывая следующее Enum:

enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}

Вы можете определить маршрут, который будет вызываться только в том случае, если {category}сегмент маршрута имеет значение fruitsили people. В противном случае будет возвращен ответ HTTP 404:

Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});

Принудительное определение области привязки маршрута

В предыдущих выпусках Laravel вы могли захотеть ограничить вторую модель Eloquent в определении маршрута, чтобы она была дочерней по отношению к предыдущей модели Eloquent. Например, рассмотрите это определение маршрута, которое извлекает сообщение в блоге по ярлыку для определенного пользователя:

use App\Models\Post;
use App\Models\User;
 
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
    return $post;
});

При использовании неявной привязки с пользовательским ключом в качестве параметра вложенного маршрута Laravel автоматически ограничивает запрос для извлечения вложенной модели его родителем, используя соглашения, чтобы угадать имя отношения для родителя. Однако такое поведение ранее поддерживалось Laravel только тогда, когда для привязки дочернего маршрута использовался пользовательский ключ.

Однако в Laravel 9.x теперь вы можете дать указание Laravel использовать область «дочерних» привязок, даже если пользовательский ключ не предоставлен. Для этого вы можете вызвать scopeBindingsметод при определении вашего маршрута:

use App\Models\Post;
use App\Models\User;
 
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
    return $post;
})->scopeBindings();

Или вы можете указать всей группе определений маршрутов использовать привязки с областью действия:

Route::scopeBindings()->group(function () {
    Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
        return $post;
    });
});

Группы маршрутов контроллера

Теперь вы можете использовать этот controllerметод для определения общего контроллера для всех маршрутов в группе. Затем при определении маршрутов вам нужно только указать метод контроллера, который они вызывают:

use App\Http\Controllers\OrderController;
 
Route::controller(OrderController::class)->group(function () {
    Route::get('/orders/{id}', 'show');
    Route::post('/orders', 'store');
});

Полнотекстовые указатели / операторы Where

При использовании MySQL или PostgreSQL этот fullTextметод теперь можно добавить к определениям столбцов для создания полнотекстовых индексов:

$table->text('bio')->fullText();

Кроме того, методы whereFullTextи orWhereFullTextможно использовать для добавления полнотекстовых предложений «где» в запрос столбцов с полнотекстовыми индексами . Эти методы будут преобразованы Laravel в соответствующий SQL для базовой системы баз данных. Например, MATCH AGAINSTдля приложений, использующих MySQL, будет сгенерировано предложение:

$users = DB::table('users')
           ->whereFullText('bio', 'web developer')
           ->get();

Движок базы данных Laravel Scout

Если ваше приложение взаимодействует с базами данных малого и среднего размера или имеет небольшую рабочую нагрузку, теперь вы можете использовать механизм «базы данных» Scout вместо специальной службы поиска, такой как Algolia или MeiliSearch. Механизм базы данных будет использовать предложения «где как» и полнотекстовые индексы при фильтрации результатов из вашей существующей базы данных, чтобы определить применимые результаты поиска для вашего запроса.

Рендеринг встроенных шаблонов Blade

Иногда вам может понадобиться преобразовать необработанную строку шаблона Blade в действительный HTML. Вы можете сделать это, используя renderметод, предоставляемый Bladeфасадом. Метод renderпринимает строку шаблона Blade и необязательный массив данных для предоставления шаблону:

use Illuminate\Support\Facades\Blade;
 
return Blade::render('Hello, {{ $name }}', ['name' => 'Julian Bashir']);

Точно так же этот renderComponentметод можно использовать для рендеринга данного компонента класса путем передачи экземпляра компонента в метод:

use App\View\Components\HelloComponent;
 
return Blade::renderComponent(new HelloComponent('Julian Bashir'));

Label name slot

В предыдущих выпусках Laravel имена слотов предоставлялись с помощью nameатрибута x-slotтега:


    
        Server Error
    
 
    Whoops! Something went wrong!

Однако, начиная с Laravel 9.x, вы можете указать имя слота, используя удобный, более короткий синтаксис:


    Server Error

Отмеченные/выбранные блейд-директивы

Для удобства теперь вы можете использовать @checkedдирективу, чтобы легко указать, установлен ли флажок для данного HTML-флажка. Эта директива будет отображаться checked, если предоставленное условие оценивается как true:

active)) />

Точно так же @selectedдиректива может использоваться для указания, следует ли «выбрать» данную опцию выбора:


    @foreach ($product->versions as $version)
        
            {{ $version }}
        
    @endforeach

Bootstrap 5 просмотров страниц

Laravel теперь включает представления разбиения на страницы, созданные с помощью Bootstrap 5 . Чтобы использовать эти представления вместо представлений Tailwind по умолчанию, вы можете вызвать метод пагинатора useBootstrapFiveвнутри bootметода вашего App\Providers\AppServiceProviderкласса:

use Illuminate\Pagination\Paginator;
 
/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Paginator::useBootstrapFive();
}

Улучшенная проверка данных вложенного массива

Иногда вам может понадобиться получить доступ к значению для данного вложенного элемента массива при назначении правил проверки для атрибута. Теперь вы можете сделать это, используя Rule::forEachметод. Метод forEachпринимает замыкание, которое будет вызываться для каждой итерации проверяемого атрибута массива, и будет получать значение атрибута и явное, полностью развернутое имя атрибута. Замыкание должно возвращать массив правил для назначения элементу массива:

use App\Rules\HasPermission;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
$validator = Validator::make($request->all(), [
    'companies.*.id' => Rule::forEach(function ($value, $attribute) {
        return [
            Rule::exists(Company::class, 'id'),
            new HasPermission('manage-company', $value),
        ];
    }),
]);

Laravel Breeze API и Next.js

Стартовый комплект Laravel Breeze получил режим формирования «API» и бесплатную реализацию внешнего интерфейса Next.js. Эта структура стартового набора может использоваться для быстрого запуска ваших приложений Laravel, которые служат в качестве бэкэнда, аутентифицированного API Laravel Sanctum для внешнего интерфейса JavaScript.

Улучшенная страница Exception

Ignition, страница отладки исключений с открытым исходным кодом, созданная Spatie, была переработана с нуля. Новое, улучшенное Ignition поставляется с Laravel 9.x и включает в себя светлые/темные темы, настраиваемую функцию «открыть в редакторе» и многое другое.

Улучшенный route:listвывод командной строки

Вывод route:listCLI был значительно улучшен для выпуска Laravel 9.x, предлагая новый прекрасный опыт при изучении ваших определений маршрутов.

Тестовое покрытие с помощью Artisan testCommand

Команда Artisan testполучила новую --coverageопцию, которую вы можете использовать для изучения объема покрытия кода, предоставляемого вашими тестами вашему приложению:

php artisan test --coverage

Кроме того, если вы хотите указать минимальный порог, которому должен соответствовать ваш процент покрытия тестами, вы можете использовать эту --minопцию. Набор тестов завершится ошибкой, если заданный минимальный порог не будет достигнут:

php artisan test --coverage --min=80.3

Сервер Soketi Echo

Хотя Laravel не является эксклюзивным для Laravel 9.x, недавно Laravel помог с документацией Soketi, совместимого с Laravel Echo сервера веб-сокетов, написанного для Node.js. Soketi предоставляет отличную альтернативу Pusher и Ably с открытым исходным кодом для тех приложений, которые предпочитают управлять собственным сервером Web Socket.

Улучшенная поддержка IDE коллекций

Laravel 9.x добавляет улучшенные, «общие» определения типов стилей в компонент коллекций, улучшая поддержку IDE и статического анализа. IDE, такие как PHPStorm , или инструменты статического анализа, такие как PHPStan , теперь будут лучше понимать коллекции Laravel.

Новые хелперы

Laravel 9.x представляет две новые удобные вспомогательные функции, которые вы можете использовать в своем приложении.

 

str

Функция strвозвращает новый Illuminate\Support\Stringableэкземпляр для данной строки. Эта функция эквивалентна Str::ofметоду:

$string = str('Taylor')->append(' Otwell');// 'Taylor Otwell'

Если функции не предоставлен аргумент str, функция возвращает экземпляр Illuminate\Support\Str:

$snake = str()->snake('LaravelFramework');// 'laravel_framework'

 

to_route

Функция to_routeгенерирует HTTP-ответ перенаправления для заданного именованного маршрута, предоставляя выразительный способ перенаправления на именованные маршруты с ваших маршрутов и контроллеров:

return to_route('users.show', ['user' => 1]);

При необходимости вы можете передать код состояния HTTP, который должен быть назначен для перенаправления, и любые дополнительные заголовки ответа в качестве третьего и четвертого аргументов метода to_route:

return to_route('users.show', ['user' => 1], 302, ['X-Framework' => 'Laravel']);