Что нового в Laravel 6.0
В этой статье узнаем, что нового добавили в Laravel 6.0, и ознакомимся с новыми функциями и обновлениями фреймворка.
Да будет Laravel 6.0! Тейлор - создатель Laravel наконец-то показал миру новую версию феймоворка Laravel. С этого момента версия 6.0 официально опубликована и доступна для всеобщего пользования. Давайте посмотрим, какие изменения были внесены в Laravel 6.0, и как мы можем взять их на вооружение в свой девелоперский арсенал.
Что нового?
Семантическое версионирование.
Хоть фреймворк и "перепрыгнул" с версии 5.8 на 6.0, Тейлор сказал, что с точки зрения новых функций и изменений, это обновление больше похоже на переход с 5.8 на 5.9.
При выпуске новых версий Laravel, всегда проделывалась огромная работа по внедрению новых фишек, что типично для молодого фреймворка. Все обновления версий 5.x являются основой стабильной и надежной структуры фреймворка. В дальнейшем, начиная с версии 6.0, вам не придется сильно беспокоиться об огромных кардинальных изменениях фреймворка и переписывать их с каждым новым мажорным выпуском. Именно по причине внедрения новой стабильности версий, фреймворк принял более традиционное семантическое версионирование, от которого разработчикам становится только лучше.
Миддлверы для Job-ов
Вместо ручного добавления дополнительных, однотипных проверок в Job-ах, теперь вы можете создать миддлвер (аналогично HTTP-миддлверам), вынеся туда общую логику, а затем просто можете привязать его к конкретному Job-у.
В этом примере я продемонстрирую, как можно добавить ограничение скорости для Job-а до 6 секунд. Ранее вы бы добавили этот код в метод handle()
добавляя этот код в каждый из Job-ов, где это требует логика работы.
// app/Jobs/JobToBeThrottled.php
// выполняем работу
public function handle() {
// задаём таймаут в 5 секунд между выполнение работ
Redis::throttle('key')->block(0)->allow(1)->every(5)->then(function () {
// выполняем работу
}, function () {
// Не удалось снять блокировку, ждём...
return $this->release(5);
});
}
В этом новом релизе теперь вы можете вынести этот код из метода handle()
и переместить его в специальный общий миддлер. Вы можете создать папку app/Jobs/Middleware
(или где угодно, Laravel не призывает к чему-то конкретному) и добавить файл нового миддлера.
// app/Jobs/Middleware/RateLimited.php
...
namespace App\Jobs\Middleware;
use Illuminate\Support\Facades\Redis;
class RateLimited {
// Выполняем работу в очереди.
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);
});
}
}
Теперь вы можете привязать этот миддлер к Job-у, и каждый Job будет проходить через этот миддлвер перед выполнение работы. Если вы знакомы с HTTP-миддлверами, который используете в контроллерах/роутах проекта, концепция одна и та же.
// app/Jobs/JobToBeThrottled.php
use App\Jobs\Middleware\RateLimited;
// указываем миддлвер, который должен сработать в Job-е
public function middleware() {
return [new RateLimited()];
}
public function handle() {
// основная логика работы, что-то тут шаманим...
}
Это позволит сохранить ваши Job-файлы небольшими, удобными для чтения и сфокусированными на решении конкретной задачи. Это также позволит вам легко повторно использовать миддлверы для Job-ов, имеющих общую логику проверок.
Ленивые коллекции
В Laravel 6.0 представлены ленивые коллекции, которые позволят вам снизить потребление памяти при работе с большими данными.
Когда вы работаете с Eloquent моделями, вы можете загружать одну модель в память за раз вместо получения всех сразу (потому что их может быть слишком много), используя метод cursor()
вместо all()
.
// Этот код загрузит все Eloquent-модели в оперативную память
// Их может быть очень большое количество, если у вас тысячи записей
$posts = App\Post::all()->filter(function ($post) {
return $post->id > 500;
});
При замене метода all()
на cursor()
, в память за один раз загружается только одна Eloquent модель, так как cursor()
использует новый экземпляр класса LazyCollection
.
$posts = App\Post::cursor()->filter(function ($post) {
return $post->id > 500;
});
foreach ($posts as $post) {
echo $post->id;
}
Eloquent улучшенная работа с подзапросами
Eloquent всегда облегчал работу со сложными запросами, создав отличную абстракцию при построении запросов. В новом релизе вам станет работать с ещё проще, когда дело доходит до выполнения подзапросов или запросов в запросе за один вызов. Это полезно, когда вам нужно выбрать информацию из двух таблиц со связями. В Laravel 5.x вы иногда ограничивались тем, что вы могли бы сделать в подзапросе, и часто всё заканчивалось тем, что были вынуждены дополнять запросы с помощью "сырого" SQL-кода DB::raw()
.
Метод addSelect
был добавлен в подзапросы, что должно устранить большую часть этой боли! Eloquent подзапросы теперь также будут иметь доступ к orderBy
.
В этом примере представьте, что у вас есть 2 таблицы: отели hotels
и reservations
брони. Вы хотите узнать, номер какого типа был зарезервирован последним для определенного отеля. Вместо того, чтобы делать два отдельных Eloqunt запроса, теперь вы можете сделать так:
use App\Reservation;
use App\Hotel;
return Hotel::addSelect(['last_booked_room' => Reservation::select('room_type')
->whereColumn('hotel_id', 'hotels.id')
->orderBy('created_at', 'desc')
->latest()
->limit(1)
])->get();
Улучшение пользовательских ответов на авторизацию
Если вы используете Laravel аутентификацию из коробки, проверяя с помощью Gate-ов авторизацию пользователей, то для вас хорошая новость - Laravel 6.0 вводит новый метод Gate::inspect()
. Он облегчает создание кастомных, пользовательских сообщений пользователям во время запросов на авторизацию. Теперь вы можете указать конкретное сообщение об ошибке, если запрос авторизации (проверки прав на доступ к данным) пользователя был отклонен.
Например, представим, что у вас есть метод, который определяет, имеет ли пользователь права на редактирование сообщения. До версии 6.0 было трудно передать конкретное сообщение о том, по каким причинам доступ был отклонён, и были некоторые трудности с отображением подобного сообщения обратно пользователю.
С добавлением метода Gate::inspect()
теперь вы можете легко задать сообщение ошибки, которое получит пользователь и отправить его ему обратно.
К примеру, если вы хотите ограничить редактирование сообщений любому пользователю, не являющимся администратором, вы бы создали Gate
правило для редактирования поста.
// App/Providers/AuthServiceProvider.php
...
public function boot()
{
$this->registerPolicies();
// Определите гейта (Gate), который проверяет, кто может редактировать сообщения
Gate::define('edit', function ($user) {
return $user->isAdmin()
? Response::allow()
: Response::deny('Только администратор может редактировать посты.');
});
}
Обычно, вы бы просто используете метод allow()
или denies()
, для того, чтобы определить, имеет ли этот пользователь права для выполнения этого действия. В результате, при выполнении этого метода, мы получим булев ответ: true
или false
, который зависит от правил, заданных в методе Gate::define()
, определенного выше. Выполнив код, как в примере, вы получите только булево значение, никаких подробностей, и пользовательских ошибок.
if (Gate::allows('edit')) {
// пользователь имеет права на редактирование...
}
if (Gate::denies('edit')) {
// пользователю запрещено редактировать запись. Ругаемся на него...
}
Но, если вы хотите получить доступ к более подробному, кастомному ответу о причине отказа, вы можете использовать метод Gate::inspect
.
// получаем подробный ответ о результате проверки авторизации пользователя
$response = Gate::inspect('edit');
if ($response->allowed()) {
// Дать пользователю возможность отредактировать этот пост
} else {
// Показать подробное сообщение о причинах отклонения
// 'Только администратор может редактировать посты.'
echo $response->message();
}
Laravel UI composer библиотека
Ещё одно обновление, о котором следует знать - это добавление нового пакета laravel/ui
. Теперь, при создании нового проекта Laravel 6.0 немного изменилась философия поставки фронтенд-окружения. С этой версии, по-умолчанию, у вам не будет установлен VueJs или Bootstrap.
Теперь ваш файл app.js
выглядит так:
require('./bootstrap');
А bootstrap.js
, убрав все комментарии, выглядит так:
window._ = require('lodash');
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
Теперь в философии Laravel нет жесткого навязывания использования VueJs, Bootstrap в проекте.
Тейлор и команда вынесли в отдельный пакет заготовки для проектов с ядром под различный фронтенд. Этот пакет теперь включает в себя пресеты для React, Vue и Bootstrap.
Для того, чтобы подключить этот пакет, установим его через composer: composer require laravel/ui
.
После чего, у нас добавятся новые ui
команды для работы с фронтендом.
// Сгенерировать базовые шаблоны...
php artisan ui vue
php artisan ui react
// Сгенерировать шаблоны с страницами login/registration
php artisan ui vue --auth
php artisan ui react --auth
Удаление ранее помеченных deprecated-хелперов
В новой версии все str_
, array_
хелперы удалены из ядра по умолчанию, и перемещены в новый пакет laravel/helpers
. Для того, чтобы вернуть старые хелперы Laravel в проект, необходимо через composer подключить этот пакет:
composer require laravel/helpers
А чтобы понять, как создать свои собственные, советую почитать статью о том, как создавать и подключать собственные хелперы.
С полным списком прочих мелких модификаций можете ознакомиться на странице.
Ребрендинг
С каждой новой мажорной версией также появляется редизайн официального сайта Laravel, и 6.0 не является исключением!
В дополнение к новому логотипу, вы также можете найти увидеть новый дизайн сайта Laravel.com.
Laravel Vapor
И последнее обновление, но не менее важное, чем остальные - запуск долгожданного продукта экосистемы Laravel - Laravel Vapor.
До Laravel Vapor большинство людей использовали Laravel Forge для деплоя и развертывания своих приложений. С помощью Forge вы можете подключит любой выбранный вами сервер (Digital Ocean, AWS и т.д.), а Forge уже сам позаботится о том, чтобы быстрее, и с вашим минимальным участием выгрузить и развернуть приложение. Это, конечно, круто, но вам всё равно приходилось вручную устанавливать некоторые компоненты/обновления.
Laravel Vapor делает всё то, что может Forge, и даже немного больше. Теперь, вместо того, чтобы самостоятельно управлять и обновлять серверы для вашего приложения Laravel, Vapor полностью избавляет вас от регистрации и управления сервером!
Конечно, это не значит, что серверы не задействованы при его работе, это просто значит, что вам не нужно иметь с ними дело, и работать с ними мануально. Следующим преимуществом является то, что вы платите только за то, что используете. Вместо того, чтобы платить фиксированную месячную ставку, вы платите только тогда, когда к вашему приложению происходят обращения. Так же, из весомых преимуществ это то, что вам не нужно беспокоиться о масштабировании, поскольку Vapor позаботится об этом за вас в автоматическом режиме.
Вот еще несколько удивительных и полезных функций, которые предоставляет Vapor:
- Масштабирование по требованию - может выполнять задачи сразу же, по мере их поступления
- Работает на основе AWS
- Готов к скачкам трафика
- Нулевой простой во время деплоя (т.е. во время обновления сайта ваше приложение не "падает" на время их применения)
- Несколько рабочих сред с возможностью бесплатного тестирования. Вы получите URL, вида https://snowy-hurricane-123456789456654.vapor.build
- Режим технического обслуживания
- Логирование с возможностью поиска
- Создавайте и масштабируйте вашей базы данных прямо из Vapor
- Резервное копирование БД и восстановление информации из бекапа
- Метрики и мониторинг данных с уведомлениями
- Возможность покупки доменов и управления их DNS-записями прямо из панели Vapor
- Автоматическое создание SSL-сертификата
- Job-ы, воркеры, обновления PHP и многое другое, настраиваемое и работающее без вашего участия, автоматически.
- Простое и легко настраиваемое развёртывание приложения с помощью простого файла
vapor.yaml
.
Стоимость всего этого составляет 39 долларов в месяц или 399 долларов в год с неограниченным количеством членов команды и проектов. Имейте в виду, что к этому всему ещё придётся добавить собственные расходы на AWS-сервера. Но, это избавляет вас от многих проблем с деплоем приложения, масштабирования и администрирования серверов вручную.
Обновление Laravel до версии 6.0
Как гласит документация Laravel, для обновления с 5.8
до 6.0
потребуется около часа. Это примерное время, так как ваш проект может иметь зависимости от сторонних библиотек, которые увеличат это время, поэтому примите это к сведению, когда решитесь обновить версию фреймворка.
Как обновить Laravel до версии 6.0
Для начала, в вашем файле composer.json
измените зависимость фреймворка Laravel с 5.8.*
На ^6.0
. Если вы используете версию более раннюю, чем 5.8
, то рекомендуется сначала выполнить обновление до 5.8
, прежде чем переходить на 6.0
.
// В вашем файле composer.json
"laravel/framework": "^6.0",
После чего, в терминале выполните:
composer update
Laravel Shift
Еще один удобный способ обновления версии фреймворка, особенно для более крупных приложений - использовать Laravel Shift. Laravel Shift - это автоматизированный инструмент, который произведёт обновление вашего приложения за вас.
Это работает так:
- Сначала предоставляем Laravel Shift доступ к вашему репозиторию приложения на Laravel
- Выберите версию Laravel, на которой в данный момент работаете, и на какую версию вы хотите обновиться
- Shift создаст новую ветку в репозитории и изменит всё то, что необходимо изменить в вашем коде для обновления
- После чего, Shift выполнит pull-request, для того, чтобы вы могли проверить и решить, следует ли его мерджить
Процесс очень простой и является идеальным вариантом, если простое изменение версии пакетов в вашем composer.json
не сработало. Услуга не бесплатная, не такая большая. Инструкцию по обновлению вы можете найти на странице.
Нужно ли обновляться?
Laravel 6.0 - это последняя версия с Long-Term поддержкой, что означает гарантированное исправление ошибок в течение двух лет, а исправления ошибок безопасности - в течение трёх лет. Предыдущий релиз LTS с аналогичными гарантиями был Laravel 5.5.
Эта таблица с сайта Laravel описывает текущий график поддержки: .
Поскольку исправление ошибок в предыдущем LTS-релизе заканчиваются очень скоро, возможно, стоит обновить его до 6.0, чтобы точно быть уверенным в том, что ваш проект будет поддерживаться ещё несколько лет.
Резюме
Laravel вызвал большой энтузиазм и волнение в мире PHP, и было здорово видеть, как фреймворк и его сопутствующие продукты продолжают улучшаться и двигать вперёд разработку. И из этой статьи вы узнали, что нового в Laravel 6.0, какие фичи были добавлены, и что было удалено в Laravel 6.0.
С введением семантического версионирования, вы сможете обновляться между мажорными выпусками, не беспокоясь об огромных, кардинальных изменениях структуры фреймворка. Этот подход означает больше, чем просто управление версиями - он показывает, что после всех улучшений, появившихся в 5.x, фреймворк теперь находится в стабильной точке, и будет двигаться только вперед на основе уже стабильного и надёжного ядра (и архитектуры)!
В дополнение к семантическому версионированию, в версии 6.0 улучшена скорость доступа к коллекциям, добавлены Eloquent-выборку в подзапросах, добавлены миддлеверы в Job-ах, и многое другое.