Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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:

Kalkulačka v PHP frameworku Laravel - Laravel framework pre PHP

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 kontroleru CalculatorController.
  • 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:

Chyba Laravel kalkulačky pri odovzdaní texte - Laravel framework pre PHP

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:

Chybové hlášky v PHP frameworku Laravel - Laravel framework pre PHP

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é 260x (11.99 MB)
Aplikácia je vrátane zdrojových kódov v jazyku PHP

 

Predchádzajúci článok
Prvé aplikácie v Laravel
Všetky články v sekcii
Laravel framework pre PHP
Preskočiť článok
(neodporúčame)
Kvíz - Výpis, routy a MVC v Laravel
Článok pre vás napísal Jan Lupčík
Avatar
Užívateľské hodnotenie:
1 hlasov
Autor se primárně věnuje vývoji webových stránek a aplikací v PHP (framework Laravel) a je jedním z herních vývojářů komunitní modifikace TruckersMP.
Aktivity