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.
