Lekce 3 - První aplikace v Laravel
V minulé lekci, Instalace Laravel a zprovoznění projektu, jsme nainstalovali a zprovoznili framework Laravel.
Dnes se vrhneme na tvorbu první jednoduché aplikace a vysvětlíme si její základní strukturu.
Volba aplikace
Jedna z aplikací, na které si můžeme demonstrovat naprosté základy a je velice jednoduchá, je kalkulačka, jejíž screenshot vidíte níže. Záměrně jsem vybral na začátek kalkulačku, protože se zatím nebudeme muset starat o databázi a konfiguraci. Místo toho si však krátce ukážeme ty nejdůležitější komponenty pro vývoj v Laravel frameworku. Zabývat se jimi do hloubky budeme až v následujících lekcích.

Tvorba kalkulačky
Jak jsme si popisovali v první lekci, Laravel je v základu postavený na MVC architektuře. Z té teď také musíme vycházet. Tvorbu naší kalkulačky tedy začneme od modelu, abychom si nejdříve vytvořili data pro pohled a metody, jež může kontroler poté ihned využít.
Model
Model si můžeme jednoduše vygenerovat přes příkazovou řádku/terminál ve složce s naším projektem. Do příkazového řádku otevřeném ve složce s projektem vložíme následující příkaz:
php artisan make:model Calculator
Příkaz na vygenerování modelu, stejně jako i další příkazy, jež dnes použijeme, má mnoho možností. Můžeme například vygenerovat CRUD kontroler k danému modelu. Jelikož to ale není pro nás nyní podstatné, budeme se tím zabývat až dále v kurzu.
Vygenerovaný model Calculator
umístěný ve složce
app/Models/
vypadá následovně:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Calculator extends Model { use HasFactory; }
Model v Laravel frameworku z většiny případů zastupuje databázovou
tabulku, proto modely už v základu dědí z třídy Model
, která
obsahuje proměnné pro definování různých atributů a hodnot a zároveň
nám poskytuje objektově relační mapování pro práci s databází. Navíc
můžeme vytvářet testovací data pro pomocí tzv. továrny. To je také důvod, proč
model již ze základu používá trait třídu HasFactory
.
Jelikož ale naše kalkulačka nebude propojená s databází, můžeme
dědění i použití trait třídy odstranit.
Nyní si definujeme metody pro 4 základní operace - sčítání, odčítání, násobení a dělení. Náš model bude vypadat následovně:
<?php namespace App\Models; /** * Model operací kalkulačky. * * @package App */ class Calculator { /** * Sečti daná čísla a vrať výsledek. * * @param int $a * @param int $b * @return int */ public function add(int $a, int $b): int { return $a + $b; } /** * Odečti druhé číslo od prvního a vrať výsledek. * * @param int $a * @param int $b * @return int */ public function subtract(int $a, int $b): int { return $a - $b; } /** * Vynásob daná čísla a vrať výsledek. * * @param int $a * @param int $b * @return int */ public function multiply(int $a, int $b): int { return $a * $b; } /** * Vyděl bezezbytku první číslo druhým a vrať výsledek. * * @param int $a * @param int $b * @return int */ public function divide(int $a, int $b): int { return floor($a / $b); } }
Naše kalkulačka bude umět počítat pouze v celých čísel. Tuto vlastnost zachováme i u dělení, kdy vracíme výsledek dělení bezezbytku. A též jste si mohli povšimnout, že neošetřujeme dělení nulou. Správně bychom toto měli ošetřit v modelu, aby mohl být znovupoužitelný i na dalších místech aplikace. Ke všemu se ale dostaneme později.
Pro počítání v celých číslech jsem se rozhodl kvůli jednoduchosti
(nemusíme např. následně zaokrouhlovat desetinná místa čísel), ale také
kvůli tomu, že si v následující lekci ukážeme validační pravidla pro
odeslaná data (přes formulář). Jedno z nich je právě
integer
.
Základní operace bychom měli. Model by však měl být rozšiřitelný a podle MVC bychom při změně modelu nejlépe neměli měnit ostatní komponenty. Přidáme si tedy do třídy ještě jednoduché rozhraní, které nám tyto vlastnosti zajistí. To znamená, že ještě definujeme následující metody a konstanty:
/** * Definice konstant pro operace. */ const ADD = 1, SUBTRACT = 2, MULTIPLY = 3, DIVIDE = 4; /** * Vrať pole dostupných operací, kde klíč je konstanta operace * a hodnota název operace. * * @return array */ public function getOperations(): array { return [ self::ADD => 'Sčítání', self::SUBTRACT => 'Odčítání', self::MULTIPLY => 'Násobení', self::DIVIDE => 'Dělení', ]; } /** * Zavolej předanou operaci definovanou konstantou a vrať její výsledek. * Pokud daná operace neexistuje, vrať null. * * @param int $operation * @param int $a * @param int $b * @return int|null */ public function calculate(int $operation, int $a, int $b): ?int { switch ($operation) { case self::ADD: return $this->add($a, $b); case self::SUBTRACT: return $this->subtract($a, $b); case self::MULTIPLY: return $this->multiply($a, $b); case self::DIVIDE: return $this->divide($a, $b); default: return null; } }
Zavedli jsme konstanty pro jednotlivé operace, metodu pro navrácení všech podporovaných operací kalkulačky spolu s jejich popisky a konečně i metodu pro výpočet, která podle operace spustí danou výpočetní metodu. V praxi by byly jednotlivé výpočetní metody samozřejmě delší a počítaly něco složitějšího, ale nám to takto jako příklad bohatě stačí.
Nyní jsme schopní jednoduše přidat další operaci do modelu a nemusíme nijak upravovat ostatní komponenty. Pokud bychom toto rozlišení podle operace vložili např. přímo do kontroleru, museli bychom při přidání nové operace již vždy upravit 2 soubory.
I když se může zdát, že se nejedná zrovna o nejideálnější řešení, v rámci našeho kurzu je toto velice dostačující a jednoduché. Zároveň díky tomu si můžeme později ukázat vlastnosti ostatních komponent jako je například validace formulářů.
Kontroler
Nyní budeme potřebovat prostředníka, který nám data zobrazí. Jak již
víme, kontroler na základě požadavku od uživatele vytvoří model a
vygeneruje pohled s daty z modelu. My budeme zatím potřebovat model
Calculator
a z něj vypsat možné operace kalkulačky. Samotný
výpočet a předání výsledku si necháme na příště.
Necháme si opět jednoduše vygenerovat kontroler s názvem
CalculatorController
přes následující příkaz v
terminálu/příkazové řádce z kořenové složky projektu:
php artisan make:controller CalculatorController
Vygenerovaný kontroler najdeme ve složce app/Http/Controllers/
a nyní nic neobsahuje krom definování třídy s názvem
CalculatorController
, dědící z Controller
.
Definujme si metodu pro zobrazení formuláře s kalkulačkou:
<?php namespace App\Http\Controllers; use App\Models\Calculator; use Illuminate\Contracts\View\View; class CalculatorController extends Controller { /** * Zobraz formulář s kalkulačkou. * * @param Calculator $calculator * @return View */ public function index(Calculator $calculator): View { return view('calculator', [ 'operations' => $calculator->getOperations(), ]); } }
Jak si můžete povšimnout, naše metoda (akce) index()
pro
zobrazení formuláře s kalkulačkou obsahuje parametr $calculator
typu Calculator
. Toto získání instance modelu v parametru
probíhá automaticky díky dependency injection,
která podle uvedeného typu pozná instanci jaké třídy chceme předat.
Jednoduše si tak vyžádáme, jaký model potřebujeme.
Uvnitř metody voláme pouze helper funkci view()
s dvěma
parametry. Jeden je pro zobrazení zatím neexistujícího pohledu s názvem
calculator.blade.php
. Dále této funkci předáváme pole s
proměnnými, které se předají pohledu. Pro nás jsou to zatím dostupné
operace kalkulačky pro formulář v pohledu. Pojďme si nyní tento pohled
vytvořit.
Pohled
Pohled si již musíme vytvořit ručně ve složce
resources/views/
. Tam můžeme také nalézt již předvytvořený
pohled s názvem welcome.blade.php
. Všimněte si, že kromě
názvu pohledu a přípony .php
název souboru také obsahuje
.blade
. Takto se označují pohledy používající šablonovací
systém Blade. Jeho základní fungování jsme si již popsali v
úvodní lekci.
My si vytvoříme vlastní pohled s názvem calculator.blade.php
s následujícím obsahem:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Kalkulačka</title> </head> <body> <h1>Kalkulačka</h1> <form method="POST" action="/calculator"> Operace: <select name="operation"> @foreach ($operations as $operation => $text) <option value="{{ $operation }}">{{ $text }}</option> @endforeach </select> <br /> První číslo: <input type="number" name="a" value="{{ $a ?? 0 }}" /> <br /> Druhé číslo: <input type="number" name="b" value="{{ $b ?? 0 }}" /> <br /> <button type="submit">Spočítej výsledek</button> </form> @if (isset($result)) <p>Výsledek je: {{ $result }}</p> @endif </body> </html>
Vývojáři Laravel frameworku se rozhodli ve verzi 6.0.0 přesunout styly a další záležitosti front-end části projektu do speciálního balíčku. Kvůli zjednodušení prvních lekcí se tímto budeme zabývat až v dílu Jednoduchý redakční systém v Laravel - Struktura projektu, kdy začneme pracovat na reálné webové aplikaci.
Pokud půjdeme krok po kroku, vytvoříme si nejdříve POST formulář
odkazující na /calculator
. Tuto routu si příště ještě
vytvoříme. Ve formuláři máme následně <select>
element
s operacemi naší kalkulačky. Pro jejich vypsání použijeme Blade notaci
@foreach ()
, která ve výsledku není nic jiného, než zkrácená
verze <?php foreach (): ?>
. Pro vypsání proměnné
používáme výraz dvojitých složených závorek, tedy {{ }}
,
jenž zobrazí a zabezpečí proměnné skrze PHP funkci
htmlspecialchars()
proti XSS
útoku.
Dále vytváříme dva elementy <input>
pro čísla. Tyto
input boxy zobrazí proměnnou s číslem pouze v případě, že daná
proměnná existuje. Proměnné budeme předávat později přes kontroler při
zpracovávání formuláře, proto se nám toto ošetřování hodí, jelikož
můžeme ten samý pohled použít pro více akcí. Konkrétně zde i pro výpis
výsledku, až bude formulář odeslaný.
Následně se výsledek ukáže na konci stránky pouze v případě, že
existuje proměnná $result
. Na toto zjištění opět použijeme
jednoduchou Blade notaci, tentokrát však @if ()
. To je však pro
tuto lekci již vše.
V příští lekci, Dokončení kalkulačky v Laravel, dokončíme kalkulačku zprovozněním odeslání formuláře a také si ukážeme, jak jednoduché je vytvořit validaci pro formulář. Budete si také moci stáhnout její zdrojové kódy pro případ, že jste měli s něčím problém.
Měl jsi s čímkoli problém? Zdrojový kód vzorové aplikace je ke stažení každých pár lekcí. Zatím pokračuj dál, a pak si svou aplikaci porovnej se vzorem a snadno oprav.