4. diel - Dokončenie kalkulačky v Laravel
V minulej lekcii, Prvé aplikácie v Laravel , sme rozpracovali jednoduchú kalkulačku v Laravel. Vytvorili sme si model, kontrolér a pohľad. Je na čase tieto časti aplikácie prepojiť.
Routovanie
Aby sme sa mohli pozrieť, ako naše aplikácie aktuálne vyzerá, potrebujeme ku kontroleru pristúpiť cez nejakú URL adresu. Na to nám slúži routovanie, jeho proces sme si popísali v úvodnej lekcii. Poďme si teraz definovať našej prvej route, ktorá kontrolér napojí na nejakú adresu.
Definované ruty pre náš web nájdeme v súbore
routes/web.php
. Tento súbor je od inštalácie nezmenený:
<?php /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::get('/', function () { return view('welcome'); });
Zatiaľ máme ako východiskový definovanú iba jednu route. Jedná sa o
zobrazenie hlavnej stránky cez GET (statická metóda get()
triedy
Route
) a spracováva sa anonymný funkcií. Takto
môžeme spracovávať akúkoľvek route. My sme si už vytvorili kontrolér a
ten tiež teraz využijeme. Na koniec súboru pridáme vlastnú definovanie GET
ruty, kde namiesto vytvorenia funkcie odkážeme na akciu nášho
kontroléra:
Route::get('calculator', 'CalculatorController@index');
Teraz ak zadáme do URL našej aplikácie /calculator
, uvidíme
nasledujúce kalkulačku:
Je na čase si kalkulačku sprevádzkovať. Vrátime sa teda ku kontroleru, kde spracujeme POST formulár.
Spracovanie odoslaní formulára
V našom kontroleru CalculatorController
si definujeme novú
metódu, ktorú pomenujeme calculate()
. Tá nám bude prijímať
požiadavky z formulára a následne zobrazovať výsledok:
/** * Zpracuj požadavek formuláře a zobraz výsledek spolu s formulářem kalkulačky. * * @param Calculator $calculator * @return View */ public function calculate(Calculator $calculator): View { $a = request()->input('a'); $b = request()->input('b'); $operation = request()->input('operation'); $result = $calculator->calculate($operation, $a, $b); return view('calculator', [ 'operations' => $calculator->getOperations(), 'result' => $result, 'a' => $a, 'b' => $b ]); }
Rovnako ako u zobrazenie kalkulačky, aj tu získavame inštanciu modelu
Calculator
do premennej $calculator
cez
dependency injection. Tá zaujímavá časť ale začína až
vo vnútri metódy.
Pre získanie odoslaných hodnôt používame metódu input()
Laravel triedy Request
, ktorú získame pomocou helper funkcie
request()
. Následne získané hodnoty použijeme pre našu metódu
calculate()
, ktorú sme si definovali v minulej lekcii v modeli
Calculator
. A ďalej zobrazíme pohľad
calculator.blade.php
cez helper funkciu view()
rovnako
ako v metóde index()
. Pohľadu opäť odovzdáme dostupné
operácie kalkulačky, navrch sme však pridali výsledok a odoslaná čísla
cez formulár, aby sme ich opäť mohli zobraziť.
Následne si vytvoríme novú route v routovacím súbore webu
routes/web.php
rovnako ako sme to urobili vyššie. Teraz si však
pridáme POST akciu:
Route::post('calculator', 'CalculatorController@calculate');
Všimli ste si, že sme definovali dve ruty s rovnakým názvom, ale jedna je GET a druhá POST? Aj napriek tomu bude naša kalkulačka bez problému fungovať. Framework si sám zistí, o aký požiadavka sa jedná, a následne zavolá danú metódu kontroleru:
- Pre zobrazenie (GET) sa teda zavolá metóda
index()
v kontroleruCalculatorController
. - Po odoslaní formulára (POST) sa zavolá
calculate()
v rovnakom kontroleru.
Ak však skúsime teraz formulár odoslať, dostaneme chybu 419 aj napriek tomu, že všetko by malo fungovať. Alebo nie?
CSRF token
Laravel chráni naše požiadavky proti CSRF útoku. Táto ochrana je spustená pre všetkých akcie, ktoré nie sú čítacie (všetky okrem GET). A čo že je vlastne ten CSRF útok?
Predstavte si situáciu, kedy sme vytvorili nejaký populárny blog a niekto by vytvoril úplne inú stránku, kam by dal formulár nabádajúce na vkladanie vulgárnych príspevkov. Tento formulár by však nenechal odosielať dáta na jeho stránku, ale na náš blog. Nič netušiaci užívatelia by razom písali príspevky na náš blog, aj keď by sa na tejto stránke vôbec nenachádzali a nevedeli, že tam niečo posielajú.
Musíme formulár teda opatriť CSRF tokenom, pomocou ktorého sa overuje, že požiadavka bola odoslaný cez našu stránku a nie cez stránku cudzie.
To sa robí pomocou Blade direktívy @csrf
, ktorá sa premení
na {{ csrf_field() }}
(tento dlhší zápis sa používal v
starších verziách). Direktívou bude formulári vygenerované skryté pole s
CSRF tokenom. Upravíme si teda formulár v pohľade
calculator.blade.php
(v priečinku
resources/views
):
<form method="POST" action="/calculator"> @csrf Operace:
Ak teraz skúsime odoslať formulár, bude už všetko fungovať tak, ako by sme si predstavovali.
CSRF ochrana pomocou middleware
CSRF ochrana je zabezpečená jedným z middlewaru Laravel frameworku. To je
vrstva, ktorou sa požiadavka spracuje ešte predtým, než sa dostane ku
kontroleru. Takéto Middleware spracovávajúci všetky akcie nájdeme
definované v súbore app/Http/Kernel.php
. Máme ich hneď
niekoľko pre skupinu web
:
protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, // \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'api' => [ 'throttle:60,1', 'bindings', ], ];
Cez tieto všetky middleware prejde našu požiadavku, než sa dostane k metóde nášho kontroleru. Môžeme vidieť, že ďalšími z nich sú napríklad šifrovanie cookies a vytvorenie relácie (session). Ak niekedy budete chcieť vytvárať svoj vlastný middleware, toto je presne miesto, kde ho budete pridávať. Následne tak bude aplikovaný pre všetky akcie na vašej webovej stránke.
Validácie formulára
Ako programátor musíme predpokladať, že nie vždy užívateľ vyplní do políčka to, čo po ňom požadujeme. Ak skúsime zadať do políčka s číslom text, naše aplikácie vyvolá chybu, pretože model dokáže prijímať iba celé čísla:
Tomu sa môžeme vyhnúť validáciou. Validačné pravidlá
možno definovať v kontroleru priamo v metóde danej akcie. My využijeme iba
pár pravidiel, všetky možno nájsť v oficiálnej
dokumentácii. V našom prípade sa jedná o to, že všetky políčka musia
byť vyplnená a že požadujeme iba celé čísla. Tiež vybraná operácia
musí byť podporovaná naším modelom. Upravíme si teda metódu
calculate()
v našom kontroleru:
/** * Zpracuj požadavek formuláře a zobraz výsledek spolu s formulářem kalkulačky. * * @param Calculator $calculator * @return View * @throws ValidationException */ public function calculate(Calculator $calculator): View { $this->validate(request(), [ 'a' => ['required', 'integer'], 'b' => ['required', 'integer', 'not_in:0'], 'operation' => [ 'required', Rule::in(array_keys($calculator->getOperations())) ] ]); $a = request()->input('a');
Začneme od anotácie, kedy miesto spracovania výnimky
ValidationException
ju odovzdáme frameworku. Ten sa o nej sám
dokáže postarať, kedy používateľa presmeruje späť is chybami, ktorých
sa dopustil.
Následne voláme metódu validate()
, ktorá je definovaná v
triede Controller
a náš kontrolér ju dedí. Tej musíme
odovzdať inštanciu triedy Request
, už možno získať opäť cez
helper funkciu request()
. Ako druhý parameter odovzdávame pole s
nastavenými overovacími pravidlami. Tie môžu byť definované len ako text.
Pre iných, ako napríklad pravidlo in
, je lepšie použiť triedu
Rule
. Tiež si všimnite, že sme vyriešili problém pre delenie
nulou, kedy druhé číslo nesmie byť 0
.
Myslím si, že ďalšie pravidlá nie je potrebné vysvetľovať, všetky sú popísané v uvedenej dokumentácii.
Ak vaše prostredie nedokáže automaticky rozpoznať triedy z iného menného priestoru, nezabudnite si na začiatok súboru triedy kontroleru pridať nasledujúce importy:
use Illuminate\Validation\Rule; use Illuminate\Validation\ValidationException;
Vypísanie chýb
Teraz už stačí len vypísať chyby v našom pohľade, aby sme informovali
používateľov o omyloch, ktorých sa dopustil. Chyby sú obsiahnuté v
premennej $errors
, tá je automaticky odovzdávaná všetkým
pohľadom. Takýchto "nedefinovaných" premenných je viac, nám však stačí
zatiaľ iba táto. Upravíme si teda náš pohľad a pod nadpis pridáme výpis
chýb:
<h1>Kalkulačka</h1> @if ($errors->any()) <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> @endif <form method="POST" action="/calculator">
$errors
je inštancia triedy ViewErrorBag
. Pre
zistenie, či ak vôbec existujú nejaké chybové hlášky, aby sme
nezobrazovali prázdny zoznam, použijeme metódu any()
. Všetky
chybové hlášky potom získame cez metódu all()
a vypíšeme je.
Ak by ste však chceli získať chybovú hlášku iba pre určité políčko,
možno použiť metódu first()
a zaslať ju názov políčka:
$errors->first('email')
Nám každopádne postačí aj len zoznam chýb
Ak skúsime zadať ako druhé číslo nulu a cez "Inspect element" (kláves F12 v prehliadači) vytvoríme neexistujúce operáciu kalkulačky, dostaneme dve chybové hlášky:
Teraz máme plne fungujúce kalkulačku vytvorenú cez Laravel, na ktoré sme si ukázali naprostej základy tohto PHP frameworku. Ak vám nie je čokoľvek jasné, stiahnite si projekt z priloženého archívu a pozrite sa na riešení. Môžete sa tiež spýtať v diskusii pod článkom, ak chcete čelíte nejakému problému. Každopádne s potrebnými znalosťami, ktoré som uviedol v prvej lekcii, by všetko malo byť po chvíľke jasné.
To je pre túto lekciu všetko. Dokončili sme kalkulačku a v budúcej lekcii, Kvíz - Výpis, routy a MVC v Laravel , sa vrhneme na nový projekt, kde sa pozrieme na niektoré časti frameworku už viac do hĺbky.
V nasledujúcom kvíze, Kvíz - Výpis, routy a MVC v Laravel, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 280x (11.99 MB)
Aplikácia je vrátane zdrojových kódov v jazyku PHP