Laravel 8 вышел 8 сентября 2020 года и содержит следующие нововведения и улучшения.
Laravel Jetstream
Laravel Jetstream — это прекрасно сдизайненный каркас приложений для Laravel. Идеальная отправная точка для создания сайтов, которая включает в себя систему регистрации и логина, верификации почты, двухфакторную аутентификацию, управление сессиями, поддержку API через Laravel Sanctum и опциональный менеджмент команды. Laravel Jetstream заменяет и улучшает устаревший каркас аутентификации предыдущих версий Laravel.
Jetstream разработан с использованием Tailwind CSS и предлагает на ваш выбор каркасы Livewire и Inertia.
Каталог моделей
По многочисленным просьбам в Laravel теперь по дефолту есть каталог app/Models
. Надеемся, что вам понравится новый дом для ваших Eloquent-моделей! Все соответствующие команды генератора обновлены. Они учитывают наличие новой директории и работают с моделями в ней. Если же такой директории нет, то фреймворк размещает модели в корне каталога app
.
Классы фабрики моделей
Фабрики Eloquent-моделей полностью переписаны и сделаны на основе классов, так же произведены улучшения для обеспечения первоклассной поддержки отношений. Например, UserFactory
, входящий в базовый состав Laravel выглядит так:
namespace Database\Factories; use App\Models\User; use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Support\Str; class UserFactory extends Factory { /** * The name of the factory's corresponding model. * * @var string */ protected $model = User::class; /** * Define the model's default state. * * @return array */ public function definition() { return [ 'name' => $this->faker->name, 'email' => $this->faker->unique()->safeEmail, 'email_verified_at' => now(), 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 'remember_token' => Str::random(10), ]; } }
Благодаря новому трейту HasFactory
, доступному для сгенерированных моделей, фабрика моделей может использоваться следующим образом:
use App\User; User::factory()->count(50)->create();
Поскольку фабрики моделей теперь являются обычными PHP-классами, то преобразования состояний могут быть записаны как методы класса. Кроме того, при необходимости, вы можете добавить любые другие хелперы в свои фабрики Eloquent-моделей.
Например, ваша модель User
может иметь состояние suspended
, изменяющее одно из её дефолтный значений атрибута. Вы можете задать свои преобразования состояний, используя метод state
из базовой фабрики. Свой метод состояния вы можете называть как угодно. В конце концов, это просто обычный PHP-метод:
/** * Указываем, что пользователь заблокирован (suspended) * * @return \Illuminate\Database\Eloquent\Factories\Factory */ public function suspended() { return $this->state([ 'account_status' => 'suspended', ]); }
После определения метода преобразования состояния мы можем использовать его таким образом:
use App\User; User::factory()->count(5)->suspended()->create();
Как уже упоминалось, в Laravel 8 фабрики моделей содержат первоклассную поддержку отношений. Предположим, что наша модель User
имеет метод отношений posts
, соответственно, мы можем просто запустить следующий код, чтобы сгенерировать пользователя с тремя сообщениями:
$users = User::factory() ->hasPosts(3, [ 'published' => false, ]) ->create();
Чтобы упростить процесс обновления, был выпущен пакет laravel/legacy-factoryies, обеспечивающий в Laravel 8 поддержку предыдущей итерации фабрик моделей.
Обновленные фабрики теперь содержат еще больше функций. Чтобы узнать о них, обратитесь к документации по тестированию баз данных.
Сжатие миграции
По мере создания приложения накапливается все больше и больше миграций. Со временем каталог может стать потенциально огромным из-за сотен файлов миграций. Теперь, если захотите, вы можете «сжать» все свои миграции в один SQL-файл. Для начала выполните команду schema:dump
php artisan schema:dump // Сдампить текущую схему базы данных и удалить все существующие миграции php artisan schema:dump --prune
В результате выполнения этой команды, Laravel запишет файл «схемы» в ваш каталог. Теперь, когда вы попытаетесь перенести свою базу данных, и никакие другие миграции еще не выполнялись, то Laravel сначала запустит SQL-файл схемы. После выполнения команд из файла схемы Laravel выполнит все оставшиеся миграции, которые не были частью дампа.
Пакетирование задач
Функция пакетной обработки задач позволит вам легко выполнять пакет задач, а после его завершения выполнять дополнительные действия.
Новый метод batch
фасада Bus
может использоваться для отправки пакета задач. Пакетирование, в первую очередь, практично в сочетании с коллбэками завершения. Таким образом, вы можете использовать методы then
, catch
и finally
для определение коллбэков завершения для пакета. Каждый из этих коллбэков получит экземпляр Illuminate\Bus\Batch
.
use App\Jobs\ProcessPodcast; use App\Podcast; use Illuminate\Bus\Batch; use Illuminate\Support\Facades\Batch; use Throwable; $batch = Bus::batch([ new ProcessPodcast(Podcast::find(1)), new ProcessPodcast(Podcast::find(2)), new ProcessPodcast(Podcast::find(3)), new ProcessPodcast(Podcast::find(4)), new ProcessPodcast(Podcast::find(5)), ])->then(function (Batch $batch) { // All jobs completed successfully... })->catch(function (Batch $batch, Throwable $e) { // First batch job failure detected... })->finally(function (Batch $batch) { // The batch has finished executing... })->dispatch(); return $batch->id;
Чтобы узнать больше о пакетировании задач, смотрите документацию по очередям.
Улучшенное ограничение скорости
Функция ограничения частоты запросов в Laravel стала более гибкой и мощной, при этом сохранив обратную совместимость с API мидлвара throttle
прошлой версии.
Ограничители скорости определяются с помощью метода for
из фасада RateLimiter
. Метод принимает название ограничителя и Замыкание, возвращающее настройку ограничения, которое должно применяться к маршрутам, присвоенных этому ограничителю:
use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Support\Facades\RateLimiter; RateLimiter::for('global', function (Request $request) { return Limit::perMinute(1000); });
Поскольку коллбэки ограничителя скорости получают экземпляр входящего HTTP-запроса, то вы можете динамически создать соответствующий ограничитель на основе входящего запроса или аутентифицированного пользователя:
RateLimiter::for('uploads', function (Request $request) { return $request->user()->vipCustomer() ? Limit::none() : Limit::perMinute(100); });
Иногда нужно сегментировать ограничения на некоторое произвольное значение. Например, вы можете разрешить пользователям доступ к заданному маршруту 100 раз в минуту на каждый IP-адрес. Для этого вы можете использовать метод by
при задании лимита:
RateLimiter::for('uploads', function (Request $request) { return $request->user()->vipCustomer() ? Limit::none() : Limit::perMinute(100)->by($request->ip()); });
Ограничители могут быть подключены к маршрутам или группам маршрутов с помощью мидлвара throttle
. Он принимает название ограничителя, который вы хотите подключить к маршруту:
Route::middleware(['throttle:uploads'])->group(function () { Route::post('/audio', function () { // }); Route::post('/video', function () { // }); });
Чтобы узнать больше об ограничителях, смотрите документацию по маршрутизации.
Улучшенный режим обслуживания
В предыдущих версиях Laravel функцию режим обслуживания php artisan down
можно было обойти с помощью списка разрешенных IP-адресов. Эта фишка удалена в пользу более простого решения «секрет»/токен.
Находясь в режиме обслуживания, вы можете использовать опцию secret
, чтобы указать токен обхода режима обслуживания:
php artisan down --secret="1630542a-246b-4b66-afa1-dd72a4c43515"
После перевода приложения в режим обслуживания вы можете перейти на URL-адрес приложения, соответствующий этому токену, и Laravel выдаст вашему браузеру cookie обхода режима обслуживания:
https://example.com/1630542a-246b-4b66-afa1-dd72a4c43515
При доступе к этому скрытому маршруту вы будете перенаправлены на адрес /
. Как только cookie будет отправлен вашему браузеру — вы сможете просматривать приложение в обычном режиме, как если бы оно не находилось в режиме обслуживания.
Предварительный рендеринг шаблона режима обслуживания
Когда вы используете команду php artisan down
во время развертывания, то ваши пользователи могут иногда сталкиваться с ошибками во время обновления ваших Composer-зависимостей или других компонентов инфраструктуры. Это происходит потому, что предварительно должна подгрузиться значительная часть фреймворка, чтобы определить, находится ли ваше приложение в режиме обслуживания, и отобразить страницу режима обслуживания с помощью механизма шаблонов.
По этой причине теперь Laravel позволяет вам заранее отрендерить шаблон режима обслуживания, который будет возвращен в самом начале цикла запроса. Этот шаблон отображается до загрузки любых зависимостей вашего приложения. Вы можете предварительно выбрать шаблон с помощью опции render
команды down
:
php artisan down --render="errors::503"
Добавление Замыканий / Цепочка catch
Используя новый метод catch
, теперь вы можете предоставить Замыкание, которое должно быть выполнено, если Замыкание в очереди не удалось выполнить после исчерпания всех попыток:
use Throwable; dispatch(function () use ($podcast) { $podcast->publish(); })->catch(function (Throwable $e) { // Эта задача сфейлилась... });
Динамические Blade-компоненты
Иногда вам может потребоваться отрендерить компонент, но вы, до момента выполнения, не знаете, какой компонент вам потребуется. В этой ситуации теперь вы можете использовать встроенный компонент dynamic-component
, базирующийся на значении или переменной.
<x-dynamic-component :component="$componentName" class="mt-4" />
Чтобы узнать больше о Blade-компонентах, смотрите документацию.
Улучшения Слушателя Событий (Event Listener)
Слушатели событий, основанные на замыкании, теперь могут быть зарегистрированы только путем передачи Замыкания в метод Event::listen
. Laravel проверит Замыкание, чтобы определить, какой тип события обрабатывает слушатель:
use App\Events\PodcastProcessed; use Illuminate\Support\Facades\Event; Event::listen(function (PodcastProcessed $event) { // });
Кроме того, Слушатели событий, на основе Замыканий теперь могут быть помечены как queueable
с помощью функции Illuminate\Events\queueable
use App\Events\PodcastProcessed; use function Illuminate\Events\queueable; use Illuminate\Support\Facades\Event; Event::listen(queueable(function (PodcastProcessed $event) { // }));
Как и для задач в очередях, вы можете использовать методы onConnection
, onQueue
и delay
для настройки выполнения очереди слушателей:
Event::listen(queueable(function (PodcastProcessed $event) { // })->onConnection('redis')->onQueue('podcasts')->delay(now()->addSeconds(10)));
Если вы хотите обрабатывать фейлы анонимного слушателя в очереди, то вы можете предоставить Замыкание в метод catch
при задании queueable-слушателя:
use App\Events\PodcastProcessed; use function Illuminate\Events\queueable; use Illuminate\Support\Facades\Event; use Throwable; Event::listen(queueable(function (PodcastProcessed $event) { // })->catch(function (PodcastProcessed $event, Throwable $e) { // Слушатель в очереди сфейлился... }));
Хелперы тестирования времени
При тестировании иногда может потребоваться изменить время, возвращаемое такими хелперами, как now
или Illuminate\Support\Carbon::now()
. Базовый класс тестирования теперь содержит хелперы, которые позволят вам управлять текущим временем:
public function testTimeCanBeManipulated() { // Путешествуем в будущее... $this->travel(5)->milliseconds(); $this->travel(5)->seconds(); $this->travel(5)->minutes(); $this->travel(5)->hours(); $this->travel(5)->days(); $this->travel(5)->weeks(); $this->travel(5)->years(); // Путешествуем в прошлое... $this->travel(-5)->hours(); // Путешествуем в определённое время... $this->travelTo(now()->subHours(6)); // Возвращаемся в настоящее время... $this->travelBack(); }
Улучшение artisan serve
В artisan-команду serve
добавлена автоматическая перезагрузка при обнаружении изменений переменных среды в вашем локальном файле .env
. Раньше приходилось это делать вручную.
Шаблоны пагинации Tailwind
Пагинатор Laravel теперь по дефолту использует фреймворк Tailwind CSS — настраиваемый, низкоуровневый CSS фреймворк, который предоставляет всё необходимое для создания нестандартных дизайнов без каких-либо раздражающих опциональных стилей, которые не так-то просто было раньше переопределить. Конечно, также остаются доступными шаблоны Bootstrap 3 и 4.
Автор: Laravel
Перевод: Алексей Широков
Наш Телеграм-канал — следите за новостями о Laravel.