Laravel 7 вышел 3 марта 2020 года и содержит следующие нововедения и улучшения.
Laravel Sanctum
Автор: Taylor Otwell
Laravel Sanctum предоставляет легковесную систему аутентификации для SPA (одностраничных приложений), мобильных приложений и простых API на основе токенов. Sanctum позволяет каждому пользователю вашего приложения сгенерировать несколько токенов API для своей учетной записи. Этим токенам могут быть предоставлены способности/области действия, которые определяют, какие действия токенам разрешено выполнять. Ранее пакет назывался Airlock.
Для получения дополнительной информации о Laravel Sanctum обратитесь к документации.
Пользовательские Eloquent Касты (Custom Eloquent Casts)
Автор: Taylor Otwell
У Laravel есть множество полезных встроенных типов приведения (кастов), но иногда вам может понадобиться сделать свои собственные. Теперь можно это сделать, реализовав интерфейс CastsAttributes
.
Классы, которые реализуют этот интерфейс, должны определить методы get
и set
. Метод get
отвечает за преобразование необработанного значения из базы данных в приведенное значение, а метод set
должен преобразовать приведенное значение в необработанное значение, которое можно сохранить в базе данных. В качестве примера, мы повторно реализуем встроенный тип приведения json
как пользовательский каст:
namespace App\Casts; use Illuminate\Contracts\Database\Eloquent\CastsAttributes; class Json implements CastsAttributes { /** * Cast the given value. * * @param \Illuminate\Database\Eloquent\Model $model * @param string $key * @param mixed $value * @param array $attributes * @return array */ public function get($model, $key, $value, $attributes) { return json_decode($value, true); } /** * Prepare the given value for storage. * * @param \Illuminate\Database\Eloquent\Model $model * @param string $key * @param array $value * @param array $attributes * @return string */ public function set($model, $key, $value, $attributes) { return json_encode($value); } }
После того как вы определили пользовательский тип приведения, вы можете подключить его к модели, используя имя его класса:
namespace App; use App\Casts\Json; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * The attributes that should be cast to native types. * * @var array */ protected $casts = [ 'options' => Json::class, ]; }
Чтобы научиться создавать свои собственные Eloquent касты, включая касты к значениям объектов, обратитесь к документации Eloquent.
Теги и улучшения для Blade-компонентов
Авторы: Spatie, Marcel Pociot, Caleb Porzio, Dries Vints, Taylor Otwell
Blade-компоненты были переработаны, чтобы получить возможность рендера на основе тегов, управления атрибутами, классами компонентов, встроенными компонентами и многого другого. Поскольку изменения были значительны, то рекомендуем ознакомиться с полной документацией по компонентам Blade
Таким образом, теперь компонент может иметь связанный с ним класс, который указывает принимаемые данные. Все публичные свойства и методы, определенные в классе компонента, будут автоматически доступны для шаблона компонента. Любые дополнительные HTML-атрибуты, указанные в компоненте, могут управляться через автоматически вставляемую переменную $attribute
, являющейся экземпляром пакета атрибутов.
Предположим, что App\View\Components\Alert
определен следующим образом:
namespace App\View\Components; use Illuminate\View\Component; class Alert extends Component { /** * Тип alert. * * @var string */ public $type; /** * Создание экземпляра компонента. * * @param string $type * @return void */ public function __construct($type) { $this->type = $type; } /** * Получение класса для данного типа alert. * * @return string */ public function classForType() { return $this->type == 'danger' ? 'alert-danger' : 'alert-warning'; } /** * Получение шаблона/содержимого компонента * * @return \Illuminate\View\View|string */ public function render() { return view('components.alert'); } }
А шаблон Blade-компонента определен так:
<!-- /resources/views/components/alert.blade.php --> <div class="alert {{ $classForType() }}" {{ $attributes }}> {{ $heading }} {{ $slot }} </div>
Компонент может быть отрендерен в другом Blade-шаблоне через тег компонента:
<x-alert type="error" class="mb-4"> <x-slot name="heading"> Содержимое Alert... </x-slot> Содержимое слота по умолчанию... </x-alert>
Это всего лишь небольшой пример функциональности обновленных компонентов Blade в Laravel 7, и он не показывает анонимные компоненты, встроенные компоненты и ряд других функций. Пожалуйста, ознакомьтесь с полной документацией компонента Blade, чтобы узнать об этой подробнее.
Предыдущий синтаксис @component для Blade-компонентов не был и не будет удален.
HTTP-клиент
HTTP-клиент является оберткой над Guzzle и сделан: Adam Wathan, Jason McCreary, Taylor Otwell.
Laravel теперь предоставляет выразительный минималистичный API для Guzzle HTTP-клиента, позволяющий быстро создавать HTTP-запросы для связи с другими веб-приложениями. Обертка над Guzzle сфокусирована на наиболее распространенных сценариях использования и опыте разработчиков. Например, клиент делает быстрый POST и взаимодействует с JSON-данными:
use Illuminate\Support\Facades\Http; $response = Http::withHeaders([ 'X-First' => 'foo' 'X-Second' => 'bar' ])->post('http://test.com/users', [ 'name' => 'Taylor', ]); return $response['id'];
Кроме того, HTTP-клиент предоставляет фантастический и эргономичный функционал для тестирования:
Http::fake([ // Заглушка для JSON ответа конечных точек GitHub... 'github.com/*' => Http::response(['foo' => 'bar'], 200, ['Headers']), // Заглушка для ответа от конечных точек Google... 'google.com/*' => Http::response('Hello World', 200, ['Headers']), // Заглушка для ответов от конечных точек Facebook... 'facebook.com/*' => Http::sequence() ->push('Hello World', 200) ->push(['foo' => 'bar'], 200) ->pushStatus(404), ]);
Чтобы узнать больше обо всех функциях HTTP-клиента, обратитесь к документации.
Быстрые операции со Строками
Автор: Taylor Otwell
Вы, вероятно, знакомы с имеющимся Laravel-классом Illuminate\Support\Str
, предоставляющий множество полезных функций для работы со строками. Laravel 7 теперь предлагает более объектно-ориентированную библиотеку для работы со строками, построенную поверх этих функций. Вы можете создать объект Illuminate\Support\Stringable
используя метод Str::of
. Затем к объекту можно цепочкой применить множество методов для работы со строкой:
return (string) Str::of(' Laravel Framework 6.x ') ->trim() ->replace('6.x', '7.x') ->slug();
Для получения дополнительной информации о методах работы со строками, пожалуйста, обратитесь к полной документации.
Улучшенная привязка модели к маршруту
Автор: Taylor Otwell
Кастомизация ключа
Иногда вы хотите получить eloquent-модель по столбцу отличному от id
. Laravel 7 позволяет вам указать нужный столбец в определении параметра маршрута:
Route::get('api/posts/{post:slug}', function (App\Post $post) { return $post; });
Автоматический скоупинг
Иногда, при неявном связывании нескольких моделей Eloquent в одном определении маршрута, вы можете захотеть определить вторую модель так, чтобы она была дочерней по отношению к первой. Например, рассмотрим ситуацию, при которой сообщение из блога извлекается слагом (slug) для определенного пользователя:
use App\Post; use App\User; Route::get('api/users/{user}/posts/{post:slug}', function (User $user, Post $post) { return $post; });
При использовании кастомной неявной привязки с ключом в качестве параметра вложенного маршрута Laravel 7 автоматически сделает запрос, чтобы получить вложенную модель по ее родителю, используя соглашения, позволяющие угадать имя отношения для родителя. Предполагается, что модель User
имеет отношение с именем posts
(множественное число от имени параметра маршрута), которое можно использовать для получения модели Post
.
Для получения дополнительной информации о привязке модели к маршруту, пожалуйста, обратитесь к документации по маршрутизации.
Множественные почтовые драйвера
Автор: Taylor Otwell
Laravel 7 позволяет сконфигурировать несколько «почтовиков» для одного приложения. Каждый почтовик, настроенный в конфигурационном файле mail
может иметь свои собственные параметры и даже свой собственный уникальный «транспорт», позволяющий вашему приложению использовать различные почтовые службы для отправки определенных почтовых сообщений. Например, ваше приложение может использовать Postmark для отправки транзакционной почты, а Amazon SES — для массовых рассылок.
По умолчанию Laravel будет использовать почтовик, настроенный как default
. Однако вы можете использовать метод mailer
для отправки сообщений, используя нужную конфигурацию:
Mail::mailer('postmark') ->to($request->user()) ->send(new OrderShipped($order));
Улучшения скорости кеширования маршрутов
Авторы: разработчики Symfony и Dries Vints.
Laravel 7 включает новый метод сопоставления скомпилированных кэшированных маршрутов, которые были кэшированы с помощью artisan-команды route:cache
. В больших приложениях (например, в приложениях с 800 или более маршрутами) эти улучшения могут привести к двукратному увеличению скорости на простом тесте «Hello World». Никаких изменений в вашем приложении это не требует.
CORS Support
Автор: Matt Barlow
Laravel 7 включает в себя поддержку Cross-Origin Resource Sharing (CORS — совместное использование ресурсов между разными источниками) интегрируя популярный пакет Laravel CORS, написанный Barry vd. Heuvel. Новая конфигурация cors
включена в дефолтный скелет приложения Laravel.
Для получения дополнительной информации о поддержке CORS в Laravel 7.x, пожалуйста, обратитесь к документации CORS.
Касты времени в запросах
Автор: Matt Barlow
Иногда вам может понадобиться сделать приведение при выполнении запроса, например, при выборе необработанного значения из таблицы. Рассмотрим следующий запрос:
use App\Post; use App\User; $users = User::select([ 'users.*', 'last_posted_at' => Post::selectRaw('MAX(created_at)') ->whereColumn('user_id', 'users.id') ])->get();
Аттрибут last_posted_at
в результатах этого запроса будет необработанной строкой. Было бы удобно, если бы мы могли применить каст date
к этому атрибуту при выполнении запроса. Для этого мы можем использовать метод withCasts
предоставленный Laravel 7:
$users = User::select([ 'users.*', 'last_posted_at' => Post::selectRaw('MAX(created_at)') ->whereColumn('user_id', 'users.id') ])->withCasts([ 'last_posted_at' => 'date' ])->get();
Улучшения очереди базы данных MySQL 8+
Автор: Mohamed Said
В предыдущих выпусках Laravel очередь database
не считалась достаточно надежной для использования на боевых серверах из-за взаимных блокировок. Тем не менее, Laravel 7 предоставляет улучшения для приложений, использующих MySQL 8+ в качестве очереди. Используя оператор FOR UPDATE SKIP LOCKED
и другие усовершенствования SQL, драйвер database
теперь можно безопасно использовать на крупномасштабных боевых серверах.
Artisan-команда test
Автор: Nuno Maduro
В дополнение к команде phpunit
вы можете теперь использовать artisan-команду test
для запуска ваших тестов. Artisan-тестировщик предоставляет прекрасную UX-консоль и множество информации о выполняемом тесте. Кроме того, он автоматически остановится при первом проваленном тесте:
php artisan test
Любые аргументы, которые могут быть переданы команде phpunit
также могут быть переданы и artisan-команде test
:
php artisan test --group=feature
Улучшения почтового шаблона Markdown
Автор: Taylor Otwell
Дефолтный почтовый шаблон Markdown получил новый, более современный дизайн, основанный на цветовой палитре Tailwind CSS. Конечно, этот шаблон может быть настроен и использован в соответствии с вашими потребностями:
Для получения дополнительной информации о Markdown, пожалуйста, обратитесь к документации.
Настройка заглушек
Автор: Taylor Otwell
Консольные artisan-команды make
используются для создания различных классов, таких как контроллеры, задачи, миграции и тесты. Эти классы создаются с использованием файлов-«заглушек», заполняемых значениями на основе вашего ввода. Однако иногда вы можете захотеть внести какие-либо изменения в эти файлы. Для этого Laravel 7 предоставляет команду stub:publish
, публикующей наиболее распространенные заглушки для последующей их настройки:
php artisan stub:publish
Опубликованные заглушки будут находиться в каталоге stubs
в корне вашего приложения. Любые изменения, внесенные в эти заглушки, будут отражены при создании соответствующих классов с помощью artisan-команд make
.
Настройка maxExceptions для Очереди
Автор: Mohamed Said
Иногда вам может потребоваться указать, что задачу можно попытаться выполнить много раз, но оно должно быть помечено как проваленное, если повторные попытки инициируются определенным числом исключений. В Laravel 7 вы можете определить свойство maxExceptions
в вашем классе задач:
namespace App\Jobs; class ProcessPodcast implements ShouldQueue { /** * Количество попыток выполнения задачи * * @var int */ public $tries = 25; /** * Максимальное количество исключений разрешенных до отказа * * @var int */ public $maxExceptions = 3; /** * Выполнение задачи * * @return void */ public function handle() { Redis::throttle('key')->allow(10)->every(60)->then(function () { // Получена блокировка, обрабатываем подкаст... }, function () { // Невозможно получить блокировку... return $this->release(10); }); } }
В этом примере задача откладывается на десять секунд, если приложение не может получить блокировку Redis и это будет повторяться до 25 раз. Тем не менее, задача провалится, если сгенерирует три необработанных исключения.
Автор: Laravel
Перевод: Алексей Широков
Наш Телеграм-канал — следите за новостями о Laravel.