Před pár dny vyšla oficiálně nová verze Laravel 6. Ačkoliv je skok z verze 5.8 na 6.0 "major" vydání, Otwell již dříve zmínil, že ve smyslu novinek a změn bude aktualizace podobná, jako by se přecházelo z verze 5.8 na 5.9. V tomto článku se detailněji podíváme, jaké novinky nám přináší.

Sémantické verzování

Laravel míval hodně zásadních změn s každou novou verzí, což je typické pro každý nový framework. Všechny změny ve verzích 5.x položili velmi stabilní základ pro robustní PHP framework. S novou verzí 6.0 se však už nemusíte tolik bát velkých změn, narušujících kompatibilitu s předchozí verzí. Díky této stabilitě framework Laravel oficiálně přešel na tradiční sémantické verzování, které ulehčí konzistenci s ostatními first-party balíčky, které toto verzování již používají.

Job middleware

S touto novou verzí můžeme extrahovat kód z metody handle() a přesunout ho specifického middlewaru. To nám umožňuje mít "jobs" menší, lépe čitelnější a obsahující pouze kód zaměřený na jejich specifický úkol. Také nám to dává možnost použít middleware pro více jobů, aniž bychom museli duplikovat kód nebo vytvářet větší komplexitu.

Do jobu tak stačí přidat novou metodu middleware() vracející pole s middleware objekty:

public function middleware()
{
     return [new SomeMiddleware];
}

Middleware pak vypadá jako každý jiný middleware:

class SomeMiddleware
{
    public function handle($command, $next)
    {
        // Akce pred zpracovanim jobu

        return $next($command);
    }
}

Middleware můžeme také zavolat během dispatchingu jobu:

SomeJob::dispatch()->through([new SomeMiddleware]);

Lazy kolekce

Laravel 6.0 nabízí možnost využít lazy kolekcí, které udržují využítí paměti na velmi nízké hodnotě a zároveň umožňují pracovat s velkým množstvím dat.

Pokud pracujete s eloquent modely, můžete využít možnosti v jednom okamžiku načíst pouze jeden model do paměti pomocí metody cursor() namísto all().

// Toto nacte vsechny eloquent modely do pameti naraz
// A to muze byt velmi velke mnozstvi pokud mate tisice zaznamu

$posts = App\Post::all()->filter(function ($post) {
    return $post->id > 500;
});

Použitím metody cursor() se v jednom okamžiku vždy do paměti uloží jen jeden eloquent model, protože metoda cursor() využívá nové instance LazyCollection.

Eloquent subquery

Eloquent vždy umožňoval lehce psát složité dotazy. S novou verzí nám navíc dává možnost provádět poddotazy, nebo dotaz v dotazu, v jediném volání. Toho se dá pak dobře využít při výběru informací z dvou tabulek, které mají nějakou vazbu. V verzích 5.x jsme byli občas limitování co můžeme v poddotazech provádět a často jsme skončili s tím, že jsme museli v dotazu použít DB::raw().

Do Eloquentu přibyla metoda addSelect, která nám práci s poddotazy velmi usnadňuje a také má přístup k metodě orderBy. Mějmě například dvě tabulky - hotely a rezervace. Potřebujeme získat nejnovější typ pokoje, který byl zarezervován pro daný hotel. Namísto toho, abychom museli provádět dva dotazy, můžeme nyní provést toto:

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();

Lepší autentizační odpovědi

Pokud používáte Laravel out-of-the-box autentizaci s bránami (gates) pro autorizaci, Laravel 6.0 nabízí novou metodu Gate::inspect. Ta umožňuje jednoduše vracet vlastní odpovědi během autorizačního požadavku, například specifickou chybovou hlášku pokud byl požadavek odmítnut.

$response = Gate::inspect('view', $flight);

if ($response->allowed()) {
    // Uzivatel muze videt pohled s letem
}

if ($response->denied()) {
    echo $response->message();
}

Nové logo, nový vzhled

S každou velkou verzí Laravel představil nový vzhled a verze 6.0 není výjimka.

Kromě nového loga Laravel také změnil vzhled stránek:

Laravel Vapor

Jedná se o aplikaci, která vám umožní dostat Laravel aplikaci bez problémů do produkce, včetně deploye. Podobnou službu nabízí již Forge, nicméně Vapor (za stejnou business cenu) využívá AWS a nabízí velkou škálovatelnost s prakticky žádnou serverovou údržbou. Více o Laravel Vapor se můžete dočíst v mém předešlém článku, kde je i video z Laraconu, kde Otwell aplikaci detailněji představuje.

Upgrade na 6.0

Laravel dokumentace odhaduje, že upgrade z 5.8 na 6.0 zabere okolo jedné hodiny. Samozřejmě projekt může mít další závislosti a externí balíčky, které tento čas ještě zvýší a je proto potřeba s tímto počítat.

V souboru composer.json změňte Laravel framework z verze 5.8.* na ^6.0. Pokud chcete přejít ze starší verze ne 5.8, pak se doporučuje prvně aktualizovat na verzi 5.8 a až poté na 6.0.

// V composer.json
"laravel/framework": "^6.0",

Poté v terminálu spusťte tento příkaz:

composer update

Laravel Shift

Další možností jak udělat upgrade, především pak pro velké aplikace, je použít Laravel Shift. Shift je automatický nástroj, který udělá celý upgrade za vás. Celý proces se provádí přes Github a Shift vytvoří pull request s novou větví, obsahující změny, které jsou potřeba pro aktualizaci. V případě, že dojde ke konfliktům, je potřeba tyto konflikty vyřešit dříve, než se pull request sloučí s hlavní větví.

Tento proces je velmi jednoduchý a nabízí dobrou možnost v případě, kdy změna verze balíčku v composer.json z nějakého důvodu nefunguje. Služba je placená, nicméně jednorázový poplatek není žádná závrátná cena (9$).

Potřebuji upgrade?

Laravel 6.0 nabízí nejnovější dlouho trvající podporu (LTS), což znamená, že fix bugů bude garantováno po dobu dvou let a security fixu po dobu tří let. Předchozí LTS verze byla Laravel 5.5.

V této tabulce můžete vidět aktuální rozpis podpory:

Verze Vydání Fix bugů do Security fixy do
5.5 (LTS) 30. srpna 2017 30. srpna 2019 30. srpna 2020
5.6 7. února 2018 7. února 2018 7. února 2019
5.7 4. září 2018 4. září 2019 4. září 2019
5.8 26. února 2019 26. února 2019 26. února 2020
6.0 (LTS) 3. září 2019 3. září 2021 3. září 2022

Fix bugů předchozí LTS verze již vypršel a proto určitě stojí za to přejít na verzi 6.0 a mít tak projekt podporován zase na několik let dopředu.