Да будет Laravel 6.0! Тейлор - создатель Laravel наконец-то показал миру новую версию феймоворка Laravel. С этого момента версия 6.0 официально опубликована и доступна для всеобщего пользования. Давайте посмотрим, какие изменения были внесены в Laravel 6.0, и как мы можем взять их на вооружение в свой девелоперский арсенал.
Семантическое управление версиями
Фреймворк Laravel теперь соответствует стандарту семантического управления версиями. Это делает фреймворк совместимым с другими пакетами Laravel, уже использующими этот стандарт. Цикл выпуска Laravel останется неизменным.
Совместимость с Laravel Vapor
Автор: Taylor Otwell
Laravel 6.0 обеспечивает совместимость с Laravel Vapor, автоматически масштабируемой безсерверной платформой для развертывания Laravel. Vapor абстрагирует сложность управления приложениями Laravel в AWS Lambda, а также сопряжения этих приложений с очередями SQS, базами данных, кластерами Redis, сетями, CloudFront CDN и многим другим.
Улучшенные ответы авторизации (Improved Authorization Responses)
Реализация: Gary Green
В предыдущих версиях Laravel было сложно получать и выставлять пользовательские авторизационные сообщения конечным пользователям. Это затрудняло объяснение им, почему конкретный запрос был отклонен. В Laravel 6.0 делать это теперь намного проще через авторизационные ответные сообщения и новый метод Gate::inspect. Например, учитывая следующий метод политики:
/**
* Определить, может ли пользователь просматривать данный рейс
*
* @param \App\User $user
* @param \App\Flight $flight
* @return mixed
*/
public function view(User $user, Flight $flight)
{
return $this->deny('Объяснение отказа.');
}
Ответ и сообщение политики авторизации могут быть легко получены при помощи метода Gate::inspect:
$response = Gate::inspect('view', $flight);
if ($response->allowed()) {
// Пользователь имеет право просматривать рейс...
}
if ($response->denied()) {
echo $response->message();
}
Кроме того, эти пользовательские сообщения будут автоматически возвращаться на фронтенд при использовании вспомогательных методов, таких как $this->authorize или Gate::authorize из ваших маршрутов или контроллеров.
Мидлвары задач (Job Middleware)
Реализация: Taylor Otwell
Мидлвары задач позволяет вам обернуть очередь задач в собственную логику, уменьшая шаблонность в самих задачах. Например, в предыдущих версиях Laravel вы могли обернуть логику метода handle задачи коллбэком с ограничением скорости:
/**
* Выполнение задачи
*
* @return void
*/
public function handle()
{
Redis::throttle('key')->block(0)->allow(1)->every(5)->then(function () {
info('Получена блокировка...');
// Выполняем задачу...
}, function () {
// Блокировка не получена...
return $this->release(5);
});
}
В Laravel 6.0 эта логика может быть перемещена в мидлвар задачи, освобождая метод ваш handle задачи от лимитирования скорости:
namespace App\Jobs\Middleware;
use Illuminate\Support\Facades\Redis;
class RateLimited
{
/**
* Обработка задачи из очереди
*
* @param mixed $job
* @param callable $next
* @return mixed
*/
public function handle($job, $next)
{
Redis::throttle('key')
->block(0)->allow(1)->every(5)
->then(function () use ($job, $next) {
// Получена блокировка...
$next($job);
}, function () use ($job) {
// Блокировка не получена...
$job->release(5);
});
}
}
После создания мидлвара их можно прикрепить к задаче, вернув из метода middleware:
use App\Jobs\Middleware\RateLimited;
/**
* Получение мидлвара, через которое должна пройти задача
*
* @return array
*/
public function middleware()
{
return [new RateLimited];
}
Ленивые Коллекции
Реализация Joseph Silber
Многим разработчикам нравятся методы Laravel Collection. Чтобы дополнить и без того мощный класс Collection, Laravel 6.0 представляет LazyCollection, использующий генераторы PHP, для работы с очень большими наборами данных, сохраняя при этом низкое потребление памяти.
Например, представьте, что вашему приложению требуется обработать файл логов размером в несколько гигабайт, используя преимущества методов Laravel Collection для анализа записей. Вместо одновременного чтения всего файла в память, ленивые коллекции могут хранить небольшую часть файла в памяти в конкретный момент времени:
use App\LogEntry;
use Illuminate\Support\LazyCollection;
LazyCollection::make(function () {
$handle = fopen('log.txt', 'r');
while (($line = fgets($handle)) !== false) {
yield $line;
}
})
->chunk(4)
->map(function ($lines) {
return LogEntry::fromLines($lines);
})
->each(function (LogEntry $logEntry) {
// обработка записи лога...
});
Или представьте, что вам нужно перебрать 10 000 моделей Eloquent. При использовании традиционных коллекций Laravel все 10 000 моделей Eloquent должны быть загружены в память одновременно:
$users = App\User::all()->filter(function ($user) {
return $user->id > 500;
});
Однако, начиная с Laravel 6.0, метод cursor в построителе запросов был обновлен и теперь возвращает экземпляр LazyCollection. Это позволяет вам по-прежнему выполнять только один запрос к базе данных, но одновременно сохранять в памяти только одну модель Eloquent. В этом примере обратный вызов filter не выполняется до тех пор, пока мы не проведем итерацию по каждому пользователю индивидуально, что позволяет значительно сократить использование памяти:
$users = App\User::cursor()->filter(function ($user) {
return $user->id > 500;
});
foreach ($users as $user) {
echo $user->id;
}
Расширения Eloquent Subquery
Реализация Jonathan Reinink
Laravel 6.0 представляет ряд новых усовершенствований и улучшений в поддержке подзапросов базы данных. Например, давайте представим, что у нас есть таблица destinations и таблица flight. Таблица flights содержит столбец arrived_at который указывает, когда рейс прибыл в пункт назначения.
Используя новую функцию выбора подзапроса в Laravel 6.0, мы можем выбрать все destinations и название рейса, который последний раз прибыл в этот пункт назначения, используя один запрос:
return Destination::addSelect(['last_flight' => Flight::select('name')
->whereColumn('destination_id', 'destinations.id')
->orderBy('arrived_at', 'desc')
->latest()
->limit(1)
])->get();
Кроме того, мы можем использовать новые функции подзапроса, добавленные в функцию orderBy, чтобы отсортировать все пункты назначения на основе того, когда последний рейс прибыл в этот пункт назначения. Опять же, это может быть сделано при выполнении одного запроса к базе данных:
return Destination::orderByDesc(
Flight::select('arrived_at')
->whereColumn('destination_id', 'destinations.id')
->orderBy('arrived_at', 'desc')
->latest()
->limit(1)
)->get();
Laravel UI
Каркас фронтенда, обычно поставляемый с предыдущими версиями Laravel, были перенесен в отдельный пакет laravel/ui. Это позволяет создавать и версионировать пользовательские интерфейсы отдельно от основного фреймворка. В результате этого изменения в дефолтном каркасе фреймворка не будет Bootstrap и Vue. Также была вынесена из фреймворка команда make:auth.
Чтобы восстановить традиционный каракас Vue/Bootstrap, имеющийся в предыдущих версиях Laravel, вы можете установить пакет laravel/ui
и использовать artisan команду ui для установки фронтенд каркаса:
composer require laravel/ui
php artisan ui vue --auth
Таким образом, существенных изменений, которые бы сделали ваши приложения несовместимыми с новой версией, не произойдёт. Однако нововведения значительно облегчат жизнь многим разработчикам Laravel.