xvital

xvital

@xvital
Praha, CZ

Web & Laravel enthusiast

Feb 26, 2019

Laravel 5.8 je vonku

xvital vytvoril tému Laravel 5.8 je vonku

Dnes bol oficiálne vydaný nový minor release, Laravel 5.8.

Prináša ďalšie vylepšenia a opravy chýb.

Pribudol nový vzťah HasOneThrough, automaticá detekcia Model Policies, Cache podla štandardu PSR-16 a mnoho iného.

Opravy chýb budú zabezpečené do 26. augusta 2019 (6 mesiacov), bezpečnostné opravy do 26. februára 2020 (12 mesiacov)

Zoznam noviniek nájdete na stránke https://laravel.com/docs/5.8/releases#laravel-5.8

Upgrade Guide

Feb 5, 2019

Resource štandardy, ktoré sa oplatí dodržiavať

xvital vytvoril tému Resource štandardy, ktoré sa oplatí dodržiavať

Už vieme ako definovať route a príslušný controller. Je ideálny čas na to, podchytiť best practice v routovaní a spracovaní požiadavok.

Resourceful?

Resource (prostriedok, zdroj) je v našom prípade niečo, nad čím operujeme. Teda konkrétny model. Pri návrhu aplikácie sa typicky zamýšľame nad tým, aké akcie budeme nad daným modelom vykonávať (čo s ním bude možné v rámci aplikácie robiť). Ak je controller resourceful, znamená to, že obsahuje všetky nižšie spomenuté akcie.

HTTP verbs

Protokol HTTP obsahuje niekoľko metód, ako odosielať požiadavku. Ide o slovesá, ktoré (veľmi trefne) popisujú, akú akciu ideme nad resourcom vykonať. Ide o týchto 5 metód/akcií: GET, POST, PUT, PATCH, DELETE.

GET získanie resourcu (R) zo servera
POST odoslanie R na server
PUT zmena R (ako celok, doslova zámena za iný, zmazanie starého a nahranie nového)
PATCH zmena R (jeho časti)
DELETE zmazanie R

Route akcie

Ak by sme chceli nad modelom vykonávať všetky akcie, môžeme ich definovať explicitne takto:

Route::get('/articles', 'ArticleController@index');
Route::post('/articles', 'ArticleController@store');
Route::put('/articles/{article}', 'ArticleController@update');
Route::patch('/articles/{article}', 'ArticleController@update');
Route::delete('/article/{article}', 'ArticleController@destroy');

Laravel však ponúka omnoho jednoduchšiu cestu s rovnakým výsledkom:

Route::resource('articles', 'ArticleController');

Ak chcete využiť len niektoré akcie, metódami only a except môžete definíciu obmedziť

// only
Route::resource('photos', 'PhotoController')->only([
    'index', 'show'
]);

// except
Route::resource('articles', 'ArticleController')->except([
    'create', 'store', 'update', 'destroy'
]);

Úplne najväčší kanón je definícia viacerých resource-ov naraz:

Route::resources([
    'articles' => 'ArticleController',
    'comments' => 'CommentController'
]);

V controlleri ArticleController zas nemusíte pracne definovať metódy pre jednotlivé akcie. Ak použijete pri vytváraní controlleru prepínač -r

php artisan make:controller ArticleController -r

vygenerovaný controller bude tzv. resourceful – bude obsahovať všetky metódy, ktoré potrebujete. Stačí len implementovať.

Prečo dodržiavť štandardy?

Ide o dôležitý štandard hlavne v prípade, že aplikácia mení majiteľa, mení sa tím, alebo prichádza nová posila. Pri použití štandardných URI a akcií controllera je veľmi jednoduche s aplikáciou (v tomto ohľade) ďalej pracovať a nie je potrebné skúmať aké názvoslovie zvolil kolega pred vami.

Ak teda chcete priniesť aplikáciou jej majiteľovi čo najvyššiu hodnotu, je aj budúca udržateľnosť aplikácie jedným z bodov, na ktorý by ste mali pri návrhu myslieť.

Jan 29, 2019

Eloquent ORM

xvital vytvoril tému Eloquent ORM

Eloquent (plynulý, ladný, dokonalý) je ORM, ktoré je súčasťou Laravelu. Tak ako hovorí samotný názov, ide o veľmi príjemné a prirodzené rozhranie pre prácu s objektami a interakcie s databázou. V jednoduchých aplikáciach tak priamo s SQL nemusíte prísť vôbec do kontaktu.

Dnes sa bližšie pozrieme na

  1. vytváranie objektov
  2. ukladanie objektov do databázy
  3. vzťahy medzi modelmi
  4. základné operácie na objektoch a ich vzťahoch

Prerekvizity

V tomto bode by ste mali mať nainštalovaný Laravel a nakonfigurovaný prístup k databáze. Pre účely ukážky práce s modelmi a vzťahmi poslúži ako príklad jednoduchá aplikácia - blog, ktorá bude obsahovať dva modely: User a Post.

Eloquent model

Je na vás aký workflow si zvolíte, prvým krokom však väčšinou bude vytvorenie modelov. Výhodou je, že Laravel v základe obsahuje jednoduchý model User a kompletnú implementáciu autentifikácie. Keďže aplikácia už model User obsahuje, vytvárať budeme už len model Post:

php artisan make:model Post -m

Použil som prepínač -m, aby mi artisan pripravil migráciu pre tabuľku posts.

Model created successfully.
Created Migration: 2019_01_29_085958_create_posts_table

V migrácii pripravíme požadovanú štruktúru tabuľky

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();

            /* Nazov clanku */
            $table->string('subject');
            /* Obsah clanku */
            $table->text('body');

            /**
             * Tabulka users je v dobe vykonavania tejto migracie uz vytvorena
             * mozeme na nu odkazovat v cudzom kluci
             */
            $table->integer('user_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

V tomto bode máme vytvorené tabuľky a môžeme sa pozrieť na model User, ktorý zatiaľ neobsahuje žiadne vzťahy, len niekoľko vlastných premenných, ktoré definujú prístup a viditeľnosť k atribútom modelu (o týchto premenných sa dozviete ďalej v článku).

Vzťah s modelom Post definujeme ako 1:N (1 užívateľ môže vytvoriť N článkov). V modeli User teda implementujeme metódu posts ako vzťah hasMany, nasledovne:

public function posts()
    {
        return $this->hasMany('App\Post');
    }

Model Post obsahuje zatiaľ prázdnu triedu Post, ktorú nám vygeneroval artisan. Sem pridáme vzťah s modelom User. Ide o opačnú stranu vzťahu 1:N, použijeme metódu belongsTo.

public function user() 
    {
        return $this->belongsTo('App\User');
    }

Vytváranie nových objektov

Na vytvorenie objektov môžeme použiť explicitný prístup: vytvoriť model, nastaviť atribúty na požadované hodnoty a nakoniec model uložiť (perzistovať ho do databázy).

$post = new Post;

$post->subject = 'Hello World!';
$post->body = 'How are you?';

$post->save();

Eloquent však na vytváranie objektov poskytuje jedoduchšiu metódu create, vďaka ktorej vytvoríte nový objekt rýchlejšie, predaním poľa s parametrami

Post::create([
      'subject' = 'Hello World!',
      'body' = 'How are you?'
]);

Používanie vzťahov medzi modelmi

Jedna z predností Active Record je práve jednoduchosť používania vzťahov. Ak chceme získať autora článku a máme k dispozícii článok

$author = $post->user;

Ak chceme zoznam článkov, ktoré napísal daný autor

$posts = $user->posts;

Tak jednoduchý môže byť prístup ku vzťahovým modelom.

Niekedy však potrebujete tento výber obmedziť/filtrovať. Volanie metódy vzťahu vracia Query Builder objekt (v tomto prípade HasMany), ktorý môžete zreťaziť s ďalšími metódami Query Buildera a samotný SQL dotaz vykonať až na konci volaním get(). Vtedy dôjde k spojeniu s databázou a vykonaniu samotnému dotazu.

// volanie vztahu a filtrovanie pouzitim where
dd($user->posts()->where('subject', 'like', '%hello%')->latest());

// vysledkom je objekt typu HasMany
HasMany {#209 ▼
  #foreignKey: "posts.user_id"
  #localKey: "id"
  #query: Builder {#206 ▶}
  #parent: User {#212 ▶}
  #related: Post {#201 ▶}
}

// to iste co vyssie, ale ukoncene volanim metody get()
dd($user->posts()->where('subject', 'like', '%hello%')->latest()->get());

// vysledkom je zoradena kolekcia objektov, ktore zodpovedaju splnaju klauzulu where
Collection {#213 ▼
  #items: array:3 [▼
    0 => Post {#214 ▶}
    1 => Post {#218 ▶}
    2 => Post {#219 ▶}
  ]
}

Eloquent obsahuje implementáciu rôznych vzťahov, ktoré budete pri vývoji aplikácií potrebovať

  • one to one
  • one to many
  • many to many
  • has many through
  • polymorfné vzťahy

Kompletný prehľad, detaily a použitie nájdete v dokumentácii.

Prednačítanie vzťahov (Eager loading)

V úvodných, jednoduchých príkladoch som využil prístup ku vzťahovým modelom cez dynamické atribúty. Veľmi praktické a jednoduché. Je však potrebné uvedomiť si, ako to celé funguje. Ak pristupujeme ku vzťahu ako k dynamickému atribútu objektu na ktorom vzťah voláme, SQL dotaz sa vykoná v danej chvíli. Ak použijete vzťah ako dynamický atribút druhýkrát, opäť sa vykoná rovnaký SQL dotaz. V určitých situáciach teda môžete zbytočne pristupovať do databázy niekoľkokrát a vyberať pri tom rovnaké dáta. Laravel preto ponúka možnosť tzv. eager loadingu, čo znamená že vzťah, resp. vzdialený objekt sa prednačíta a stane sa súčasťou vybraného objektu. Pre prístup k dátam vzdialeného objektu už nebude potrebné dotazovať sa do databázy.

Fillable, guarded a hidden atribúty modelov

V triede modelu môžete obmedziť hromadné vyplňovanie atribútov. Slúžia na to špeciálne premenné $fillable a $guarded. Guarded – je zoznam chránených atribútov, ktoré bude Laravel za vás strážiť, aby sa nevypĺňali hromadne (napríklad pri použití metódy create). Všetky atribúty, ktoré nebudú definované v tomto zozname, bude možné vypĺňat hromadne. Fillable – je má inverznú funkciu ako guarded – atribúty vymenované v zozname sa budú dať hromadne vypĺňať, u ostatných to možné nebude. Zoznamy definujete ako pole atribútov. Používajte podľa potreby buď guarded, alebo fillable. Ak chcete, aby niektoré atribúty modelu neboli obsiahnuté v dátach, ktoré vám Eloquent vráti, definujte ich v premennej $hidden. Podobne ako u vyššie uvedených, definujete skryté atribúty ako pole atribútov. Vhodné hlavne pre atribúty, ktoré môžu predstavovať bezpečnostné riziko.

Ako vždy, detailné informácie a hlavne mnoho ďalších funkcií a možností, ktoré ponúka Eloquent, nájdete v dokumentácii pre ORM Eloquent.

Laravel Snippet #3

xvital vytvoril tému Laravel Snippet #3

Laravel Snippet - týždenný sumár Taylora Otwella, na čom pracoval Laravel team v uplynulom týždni je tu opäť.

<iframe src='https://share.transistor.fm/e/ac3cc392&#039; width='100%' height='180' frameborder='0' scrolling='no' seamless='true' style='width:100%; height:180px;'></iframe>

Snippet #3 Highlight: Prístup k migráciam, rollback a metóda down()

Taylor hovorí o tom, že v produkčnom prostredí ešte asi nikdy nepoužil rollback. Podobne ako väčšina Laravel vývojárov, využíva len dopredný prístup a v prípade potreby migruje všetky migrácie od začiatku príkazom php artisan migrate:fresh. V prípade že potrebuje štruktúru databázy upraviť, vytvorí k tomu novú migráciu. Podobný prístup som spomenul v článku o Databáze a migráciach.

Laravel Snippet #2

xvital vytvoril tému Laravel Snippet #2

<iframe src='https://share.transistor.fm/e/8061adf9&#039; width='100%' height='180' frameborder='0' scrolling='no' seamless='true' style='width:100%; height:180px;'></iframe>

Highlight tohto Snippetu: Je Lumen mŕtvy?

Lumen nie je mŕtvy. Je to mikroframework, kde (už z definície) nepribúda množstvo nových funkcií rýchlym tempom, ako to môžeme vidieť v klasických frameworkoch. Na pohľad sa teda môže zdať, že Lumen sa nevyvíja a Laravel team mu nevenuje pozornosť, v skutočnosti však Lumen ide svojou cestou a málo aktivity neznamená, že by bol na odpis.

Jan 26, 2019

Databáza a migrácie

xvital vytvoril tému Databáza a migrácie

Keď už vieme ako Laravel zabezpečuje perzistenciu modelov v databáze, môžeme prejsť na samotnú databázu a jej konfiguráciu. V tomto článku sa pozrieme na konfiguráciu a používanie databáz v Laraveli.

Konfigurácia

Konfigurácia a nastavenia v Laraveli vo všeobecnosti majú dve úrovne. Adresár config obsahuje jednotlivé konfiguračné súbory pre rôzne časti aplikácie a služby, resp. balíčky. Potom je tu .env súbor, kam môžete vytiahnuť niektoré premenné, ktoré majú byť závislé na prostredí. .env súbor by sa pri deploymente nemal distribuovať. Vďaka tomu bude konfigurácia zodpovedať danému prostrediu, bez potreby meniť hodnoty pri opakovanom deploymente (úpravy/oprava chýb).

Najčastejšie zrejme budete využívať databázu MySQL (MariaDB). Konfigurácia je v rámci novej inštalácie Laravelu pripravená na použitie MySQL, takže stači v súbore .env nastaviť správne údaje pre pripojenie k databáze.

Ak chcete zmeniť prednastavený typ spojenia, stačí otvoriť súbor config/database.php a upraviť hodnotu default podľa potreby. Pripojenia spravujete v tom istom súbore, o niečo nižšie, pod kľúčom connections.

Ak ste zadali správne údaje, môžete vyskúšať spustiť migráciu (pomocou php artisan migrate) a uvidíte, či zbehnú vstavané migrácie v poriadku.

Migrácie

Veľmi efektívne a využiteľné rozhranie pre prácu so štruktúrou databázy vám dávajú v Laraveli migrácie. Ide o zaujímavý koncept, ktorý pripomína verzovanie v svn alebo git.

Ako to funguje?

V databáze je pre účely migrácií vytvorená veľmi jednoduchá servisná tabuľka migrations, ktorá obsahuje záznamy o tom, ktoré migrácie už boli vykonané. Každý zásah do štruktúry tabuliek sa potom robí v rámci novej migrácie. Databáza prejde vykonaním migrácie do nového stavu. Vďaka tomu môžete robiť zásahy aj do produkčnej databázy bez toho, aby ste museli dáta exportovať, (v extrémnom prípade upravovať) a znova importovať do upravenej databázy. Stačí správne napísať migráciu.

Nikde však nie je striktne uvedené, ako pristupovať k migráciam. Môžete vytvárať migrácie pri vytváraní modelov s prepínačom -m a mať tak oddelené migrácie pre jednotlivé tabuľky modelov. Osobne využívam skôr prístup, kedy sa v rámci jedného cyklu od návrhu až po deployment snažím udržiavať všetky úpravy na úrovni databázy v jedinej migrácii. Získam tak výhodu nižšieho počtu migračných súborov, lepší prehľad a lepšiu kontrolu nad migráciami – pri každom deploymente sa vykoná maximálne jedna. Záleží však aj od konkrétnej situácie, a niekedy dáva väčší zmysel oddeliť jednotlivé úpravy/vytváranie podľa logických celkov a nemiešať všetko dohromady. Vyberte si akýkoľvek prístup, ktorý vyhovuje vám, konkrétnemu projektu a vášmu workflow.

Vytváranie migrácii

Novú migráciu vytvoríte príkazom

php artisan make:migration nazov_migracie

Pre urýchlenie a zjednodušenie práce s vygenerovanými súbormi migrácii môžete využiť prepínače --create a --table, ktoré hovoria o tom, ktorej tabuľky sa bude migrácia týkať. Pripravený súbor tak bude obsahovať viac informácií - menej práce s úpravou.

Štruktúra súborov

Trieda migrácie obsahuje dve metódy: up a down. V metóde up hovoríme, čo sa má vykonať pri vykonávaní migrácie (napr. vytváranie tabuliek, pridávanie nových stĺpcov, zmena názvov stĺpcov a pod.) a v metóde down by sme mali tieto akcie zas vziať späť. V ideálnom prípade sa databáza po vykonaní migrácie a jej rollbacku dostane znova do pôvodného stavu. V reálnom svete väčšina vývojárov metódu down vôbec nevyužíva, resp. v nej len v prípade vytvárania tabuliek v rámci migrácie prevádzajú ich drop. Taylor Otwell sa k tejto problematike vyjadril v Laravel Snippet #3.

Všetky potrebné funkcie pre vytváranie tabuliek, stĺpcov, úpravy, vytváranie FK, indexov a množstvo ďalších vecí nájdete priamo v dokumentácii. Ak by ste s potrebovali pomôcť s konkrétnou vecou, stačí sa ozvať tu na fóre.

Prístup k dátam

Priamočiary prístup k dátam na vyššej úrovni zabezpečuje ORM Eloquent, ktorý mapuje stĺpce tabuliek modelov na atribúty modelov v PHP. Viac o Eloquente a Active Record implementácii som napísal v staršom blogu. Tejto téme sa ešte budem venovať v článku o Eloquente.

Druhý prístup (nižšej úrovne) ponúka Query Builder a fasáda DB. Ak potrebujete vo vašej aplikácii pristupovať k dátam zložitejšími dotazmi, Query Builder je rozhranie, ktoré hľadáte. Na stránkach dokumentácie pre Query Builder nájdete (takmer) nekonečné množstvo užitočných funkcií, ktoré zabezpečujú konvenčný prístup k databáze. Ak by vám ani toto nestačilo, je vám k dispozícii metóda raw na čisté SQL dotazovanie. Dohromady je k dispozícii veľmi silný nástroj, ktorý zaručene pokryje všetky vaše potreby.

Jan 23, 2019

Laravel 5.7.22

xvital vytvoril tému Laravel 5.7.22

Včera vyšiel nový release, 5.7.22. Nový patch obsahuje jednu opravu chyby a niekoľko úprav. Konkrétne:

Fixed

Fixed TestResponse::assertJsonValidationErrors() when there are no errors (#27190)

Changed

Allowed TestResponse::assertJsonMissingValidationErrors() to be called without an argument (#27176) Updated vue preset's vue-stubs for laravel-mix 4 compatibility (#27229) Updated preset to use @babel/preset-react (#27235) Used config to resolve the database value during tests. (#27240)

Jan 20, 2019

Taylor Otwell: Laravel Snippet #1

xvital vytvoril tému Taylor Otwell: Laravel Snippet #1

<iframe src='https://share.transistor.fm/e/57a1e430&#039; width='100%' height='180' frameborder='0' scrolling='no' seamless='true' style='width:100%; height:180px;'></iframe>

Jan 19, 2019

Laravel a Active Record

xvital vytvoril tému Laravel a Active Record

Ďalším dielom základov v Laraveli by logicky mala byť databáza alebo ORM Eloquent. Predtým, než sa pozrieme na to, ako Laravel pracuje s databázou si však povedzme niečo o tom, ako Laravel pracuje s dátami na úrovni modelov a ako zabezpečuje perzistenciu modelov v databáze.

ORM – mapovanie objektov do relačnej databázy

Existencia modelov je ohraničená PHP runtimeom, sú teda, len dočasné. Na to, aby sme dáta modelov zachovali, potrebujeme modely uložiť tzv. perzistentne. Ako úložisko sa vo webových aplikáciach najčastejšie využívajú relačné databázy. Prístupov k mapovaniu objektov do databázy je však viacero. Dva, v rámci webových frameworkov najčastejšie používané, sú Active Record a Data Mapper.

Active Record vs. Data Mapper

Zatiaľ čo v rámci Data Mapper prístupu definujete prepojenie dát s databázou explicitne, Active Record implicitne mapuje stĺpce tabuľky 1:1 na atribúty modelu.

V AR typicky využívame pri práci s modelmi workflow:

$thread = new Thread;
$thread-&gt;subject = &#039;Example Thread&#039;;

$thread-&gt;save();

V prípade Data Mapper by základ vyzeral podobne:

$thread = new Thread;
$thread-&gt;subject = &#039;Example Thread&#039;;

ThreadMapper::persist($thread);

Model Thread však nemá informácie o štruktúre databázy a je len obyčajným PHP objektom, preto na uloženie potrebujeme zavolať službu, ktorá model do databázy uloží. Výhodou je, že je len objektom a sám sa nezaoberá svojou perzistenciou. To za neho rieši príslušný, oddelený mapper v inej vrstve, ktorý má na starosti mapovanie atribútov modelu do tabuľky.

Active Record túto vrstvu neobsahuje, vďaka čomu môže byť vývoj omnoho jednoduchší a rýchlejší. Na druhej strane to predurčuje využitie vzoru na určitý typ aplikácií; Je excelentný pre domény, ktoré neobsahujú zložitú biznis logiku a predovšetkým tie, kde je práca s dátami skutočne priamočiara – CRUD.

Čím viac logiky pri vyberaní/zapisovaní dát do databázy potrebujete, tým menej výhodný tento model bude – spoznáte to napríklad podľa neštandardne dlhých tried modelov.

Eloquent ORM = Active Record

Laravel vo svojom ORM Eloquent implementuje vzor Active Record. Dobrou správou pre tých, ktorí nad Laravelom uvažujú je, že veľa webov si s CRUD operáciami do veľkej miery vystačí, pretože fungujú ako rozhranie na vytváranie/zobrazovanie obsahu.

Pre tie ostatné je na mieste zamyslieť sa pred návrhom nad tým, či ísť cestou priamych queries v Laraveli a obchádzať tak ORM Eloquent, alebo sa viac oplatí siahnuť po inom ORM (alebo aj celom frameworku) implementujúcom vzor Data Mapper a definovať mapovanie podľa potrieb aplikácie v oddelenej vrstve (DM).

Jan 16, 2019

Laravel 5.7.21

xvital vytvoril tému Laravel 5.7.21

Zhruba týždeň po vydaní patchu 5.7.20 včera vyšiel ďalší - 5.7.21. Pozrime sa bližšie na to, čo sa opravovalo.

Fixed

  • Fixed Blueprint::removeColumn() (#27115, #27122)
  • Fixed allowing of null broadcast connection driver (#27135)
  • Fixed ModelMakeCommand::handle() should always return bool value (#27156)
  • Fixed TestResponse::assertSessionDoesntHaveErrors() when there is no errors (#27145)
  • Fixed default message in localization twice in 403.blade.php error page (4a08120)

Changed

  • Replaced get_called_class() to static::class (#27146)
  • Re-throw NoMatchingExpectationException from PendingCommand (#27158)

Zdroj: https://github.com/laravel/framework/blob/5.7/CHANGELOG-5.7.md#v5721-2019-01-15

Generovanie výstupu a Laravel Blade šablóny

xvital vytvoril tému Generovanie výstupu a Laravel Blade šablóny

Pozrime sa bližšie na to, ako v Laraveli oddelíme generovanie a formátovanie výstupu od logiky aplikácie. V článku o routingu som uviedol príklad, ako môžeme vygenerovať výstup priamo z route súboru web.php. Vyzeral približne takto:

Route::get(&#039;test&#039;, function () {
    return &#039;Môj prvý výstup&#039;;
});

V reálnej aplikácii však budeme generovať zložitejší, štruktúrovaný výstup v HTML. Posielať ho na výstup takýmto spôsobom by bolo veľmi nepraktické, preto využijeme oddelené súbory - šablóny. V Laraveli sú súbory šablón organizované v adresári resources/views a tu bude hľadať naše šablóny aj pomocná funkcia (helper) view. Namiesto vyššie uvedeného príkladu použijeme:

Route::get(&#039;test&#039;, function () {
    return view(&#039;test&#039;);
});

V adresári resources/views vytvoríme súbor test.blade.php (súbory šablón majú koncovku .blade.php). Do príkladu pridám aj základnú HTML štruktúru:

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Hello World!&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;

    &lt;h1&gt;Hello World!&lt;/h1&gt;

&lt;/body&gt;
&lt;/html&gt;

Na endpointe /test prehliadač zobrazí nadpis prvej úrovne „Hello World!“

Blade a šablónovanie

Už vieme, ako generovať výstup definovaný v oddelenom súbore. Samo o sebe by nám to však veľmi nepomohlo, pokiaľ by sme museli každé zobrazenie (view) webu definovať ako samostatný nezávislý súbor – množstvo kódu by sa opakovalo a úpravy by boli doslova nočnou morou. Vo vytváraní štruktúry šablón nám pomôže prepracovaný šablonovací engine Blade. Blade je veľmi výkonný nástroj na šablónovanie, ktorý prináša veľké možnosti s minimálnou, resp. žiadnou réžiou navyše vďaka tomu, že šablóny sa prekladajú do PHP a udržiavajú sa medzi úpravami v cache. V Blade šablónach je možné používať aj čisté PHP.

Skladanie šablón

Aby sme zabránili opakovaniu rovnakého kódu v zobrazeniach, opakujúce sa časti môžeme združiť do základnej šablóny, ktorá nám poslúži ako základ, ktorý budeme rozširovať vo vnorených šablónach. Základnú šablónu nazvem napríklad overall.blade.php. V našom prípade by mohla vyzerať napríklad takto:

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;@yield(&#039;title&#039;)&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;

    @yield(&#039;content&#039;)

&lt;/body&gt;
&lt;/html&gt;

Povedzme, že chceme vytvoriť uvítaciu stránku s nadpisom a krátkym textom. Šablóna nižšej úrovne pages/home.blade.php bude vyzerať napríklad takto:

&lt;!-- pages/home.blade.php --&gt;

@extends(&#039;overall&#039;)

@section(&#039;title&#039;, &#039;Hello World!&#039;)

@section(&#039;content&#039;)
    &lt;h1&gt;Hello World!&lt;/h1&gt;
        &lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.&lt;/p&gt;
@endsection

Blade syntax je veľmi jasná a väčšina direktív funguje presne tak, ako by ste čakali. Direktíva @extends definuje šablónu, ktorú rozširujeme, @section definuje jednotlivé sekcie rodičovskej šablóny. Pre vygenerovanie kompletného zobrazenia použijeme šablónu najnižšej úrovne – v tomto prípade home.blade.php:

Route::get(&#039;home&#039;, function () {
    return view(&#039;pages.home&#039;);
});

Všimnite si . Zápis. Dá sa použiť aj klasický zápis pomocou lomítka (forward slash), je však lepšie zvyknúť si na zápis s bodkami, je to totiž štandard, ktorý Laravel využíva aj mimo Blade súborov.

Posielanie dát do šablón

Druhým parametrom funkcie view() je nepovinné pole s predávanými dátami. Kľúče tohto poľa budú v šablóne dostupné ako premenné rovnakého názvu. Ak by sme teda chceli posunúť našej uvítacej šablóne nejaké dáta, môžeme to urobiť takto:

Route::get(&#039;home&#039;, function () {
    return view(&#039;pages.home&#039;, [&#039;name&#039; =&gt; &#039;John&#039;]);
});

V súbore šablóny vypíšeme premennú $name

@extends(&#039;overall&#039;)

@section(&#039;title&#039;, “Hello {$name}“)

@section(&#039;content&#039;)
    &lt;h1&gt;Hello {{ $name }}!&lt;/h1&gt;
        &lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.&lt;/p&gt;
@endsection

Syntax {{ }} zabezpečuje výpis a ide v podstate o volanie PHP funkcie echo. Táto syntax sa používa na tzv. bezpečný výpis. Je zabezpečená proti XSS útokom tým, že vstup prechádza PHP funkciou htmlspecialchars. Ak potrebujete vypísať neescapovaný obsah, môžete použiť syntax {!! $var !!}, ale rozhodne týmto spôsobom nevypisujte dáta od užívateľa. Mohli by ste sa stať zraniteľný XSS útokom. Syntax základných kontrolných štruktúr nájdete v dokumentácii.

Vkladanie šablón

Na vloženie obsahu inej šablóny môžeme použiť Blade direktívu @include, ktorá má niekoľko variánt – viď dokumentácia @include. Základná syntax @include

@include(&#039;view.name&#039;, [&#039;some&#039; =&gt; &#039;data&#039;])

Rovnako ako pri funkcii view, aj tu je druhý parameter – pole predávaných dát nepovinné.

Záver

V článku sme prešli základmi šablónovania a oddeľovania zobrazení od logiky aplikácie. Blade šablóny sú veľmi silným nástrojom na generovanie a formátovanie výstupu aplikácie s priamočiarou, jednoduchou syntaxou. Všetky detaily nájdete v dokumentácii na oficiálnych stránkach. Zaujímavosti a menej bežné direktívy si ukážeme v niektorom z ďalších článkov.

Jan 14, 2019

Controllery – ich význam a základy používania

xvital vytvoril tému Controllery – ich význam a základy používania

V tomto blogu nadviažem na posledný článok o routingu. Controllery s routami dosť úzko súvisia.

Controller je základným kameňom každej, aspoň trochu rozsiahlejšej aplikácie. Primárnou úlohou controllerov je oddeliť logiku spracovania požiadavky od zvyšku aplikácie. Bez tejto abstrakcie by boli naše route súbory obrovské, pretože by obsahovali celú logiku spracovania požiadaviek.

Ako sa však dostane požiadavka do controllera? Vďaka routeru. V route file sme zadefinovali, ktorý controller má spracovať požiadavku smerovanú na daný endpoint aplikácie. Laravel sa postará, aby naša požiadavka dorazila do príslušného controllera a tam ju môžeme spracovať.

Definícia route a controllera

Pripomeňme si, ako vyzerá základná definícia cesty v route súbore, ktorá zabezpečí spracovanie GET požiadavky zaslanej na endpoint forum, controllerom ThreadController – konkrétne jeho akciou (metódou) index:

Route::get(&#039;/forum&#039;, &#039;ThreadController@index&#039;);

Súbor controllera je možné vytvoriť v app/Http/Controllers, omnoho jednoduchšie je však použiť vstavaný artisan príkaz

php artisan make:controller ThreadController

ThreadController by mohol v tomto prípade po implementácii metódy index vyzerať napríklad takto:

&lt;?php

namespace App\Http\Controllers;

use App\Thread;
use App\Http\Controllers\Controller;

class ThreadController extends Controller
{
    /**
     * Zobrazenie zoznamu 10 najnovsich tem fora.
     *
     * @param  int  $id
     * @return View
     */
    public function index()
    {
        $threads = Thread::latest()-&gt;take(10)-&gt;get();

        return view(&#039;thread.index&#039;, compact(&#039;threads&#039;));
    }
}

Jednoúčelový controller (controller s jedinou akciou)

Menej bežná je definícia controllera s jedinou akciou. V určitých prípadoch však môže prísť táto možnosť vhod. Namiesto definície jednotlivých akcií zadefinujete jedinú metódu __invoke v triede controllera.

Route by potom vyzeral napríklad takto

Route::get(&#039;/forum&#039;, &#039;IndexController&#039;);

Trieda controllera by v tomto prípade obsahovala obsahovala implementáciu metódy __invoke

public function __invoke()
{
    $threads = Thread::latest()-&gt;take(10)-&gt;get();

    return view(&#039;thread.index&#039;, compact(&#039;threads&#039;));
}

Pri použití jednoúčelového controllera môžete využívať všetky ostatné možnosti (predávanie parametrov, explicitná definícia konštruktora, …). artisan podporuje aj vytváranie jednoúčelových controllerov, stačí použiť prepínač --invokable.

Štandardné akcie controllerov

Dobrým zvykom je používať štandardné akcie controllerov vždy, pokiaľ to je možné. Je to štandard, ktorý zabezpečí, že váš kód bude ľahšie pochopiteľný a rýchlejšie čitateľný. Preto rozhodne odporúčam dodržiavať. Prehľadnú tabuľku nájdete priamo v dokumentácii.

Pre vytvorenie resource controlleru (obsahuje všetky uvedené akcie), môžete použiť pri vytváraní controlleru prepínač --resource. Ak chcete do jednotlivých metód automaticky vložiť aj triedu modelu na ktorý sa controller vzťahuje (type-hinting), použite pri vytváraní controlleru prepínač --model=NazovModelu.

Jan 12, 2019

Základy routovania v Laraveli

xvital vytvoril tému Základy routovania v Laraveli

Routing je fundamentom každého webovo orientovaného MVC frameworku, no nie je špecifikom MVC - routing sa používa aj inde. Router prichádza ako prvý do kontaktu s požiadavkou. Obsahuje logiku spracovania, alebo jej ďalšieho presmerovania. V rámci rozdelenia zodpovednosti v modeli MVC je logika spracovania požiadavky oddelená do tzv. controllerov, ktoré preberajú zodpovednosť za spracovanie.

Dlhú dobu Laravel v defaulte obsahoval jediný súbor routes.php, kde boli definované všetky routy na jednom mieste. Od verzie 5.3 však bol tento súbor premiestnený do samostatného adresára routes v koreňovom adresári projektu a rozdelený do viacerých súborov. Na routy v súbore routes/web.php sa aplikuje middleware web (stavy, CSRF), zatiaľ čo na routy v súbore routes/api.php sú bezstavové a aplikuje sa na ne middleware api.

Route definície

Najjednoduchšia možnosť ako zadefinovať route a poslať do prehliadača dáta je použitie callbacku priamo v route súbore. V tomto prípade sa stáva Router zároveň controllerom, keďže zodpovednosť za spracovanie požiadavky neposúva na dedikovaný controller.

Route::get(&#039;test&#039;, function () {
    return &#039;Môj prvý výstup&#039;;
});

Táto metóda routingu môže poslúžiť napríklad pri ladení aplikácie, oveľa častejšie však pre aplikácie bežného rozsahu v MVC využijete nasledujúcu metódu, kde ako callback uvediete dedikovaný controller a jeho metódu, ktorá bude požiadavku spracovávať

Route::get(&#039;dashboard&#039;, &#039;DashboardController@index&#039;);

Fasáda Route umožňuje definíciu všetkých dostupných HTTP metód (get, post, put, patch, delete, options). Keďže HTML formuláre do verzie HTML 4, resp. XHTML 1 podporujú len metódy GET a POST, na využívanie ďalších metód potrebujeme vo formulároch definovat skryté pole (tzv. form method spoofing, o ktorom si povieme viac v článku a pokročilom routovaní).

Parametrické URI

V aplikáciach často potrebujeme definovať parametrické URI, teda URI s premennými segmentami. Na definíciu parametrov použijeme zložené zátvorky {}.

Route::get(&#039;/thread/{slug}&#039;, function ($slug) {
    return $slug;
});

resp.

Route::get(&#039;/thread/{slug}&#039;, &#039;ThreadController@show&#039;);

Parametrov môže byť viac.

Route::get(&#039;/{user}/{slug}&#039;, &#039;ThreadController@show&#039;);

Parametre môžu byť nepovinné

Route::get(&#039;/thread/{slug?}&#039;, &#039;ThreadController@show&#039;);

Parametre je možné obmedziť regulárnym výrazom

Route::get(&#039;/thread/{slug}&#039;, &#039;ThreadController@show&#039;)-&gt;where(&#039;slug&#039; =&gt; &#039;[a-z-]+&#039;);

Veľmi praktická možnosť je dať niektorým routam (podľa použitia) názov. Práca s nimi je potom rýchlejšia, jednoduchšia a prehľadnejšia.

Route::get(&#039;/thread/{slug}&#039;, &#039;ThreadController@show&#039;)-&gt;name(&#039;thread.show&#039;);

Na generovanie URL z pomenovanej routy nám poslúži funkcia route

route(&#039;thread.show&#039;, [&#039;slug&#039; =&gt; &#039;hello-world&#039;]);
// thread/hello-world

Routovanie v Laraveli je pomerne jednoduchá záležitosť. V tomto blogu som zhrnul základné možnosti, ktoré využijete najčastejšie. Užitočných možností je však omnoho viac. Pre lepší prehľad odporúčam prejsť dokumentáciu routingu.

Ďalší blog o controlleroch vám predstaví základné princípy oddelenia logiky spracovania požiadavky do samostatných súborov.

Jan 11, 2019

Laravel - inštalácia a základná konfigurácia

xvital vytvoril tému Laravel - inštalácia a základná konfigurácia

Inštalácia samotného frameworku je rýchla a nenáročná. Pred tým než sa do inštalácie pustíte sa však uistite, že vaše vývojové prostredie spĺňa všetky požiadavky. Serverové požiadavky podľa verzie frameworku nájdete v dokumentácii.

Podmienkou pre inštaláciu je mať nainštalovaný Composer (správca závislostí).

Stačí zavolať príkaz

composer global require laravel/installer

Po pridaní globálneho vendor adresára do $PATH (premennej prostredia) môžete používať na vytvorenie nového projektu jednoduché volanie laravel new nazov-projektu Toto volanie vytvorí nový Laravel projekt a nainštaluje všetky preddefinované závislosti.

Vývojové prostredie, lokálny server

Možností ako pracovať lokálne je niekoľko. PHP CLI od verzie 5.4.0 disponuje vstavaným webserverom, ktorý je pre potreby vývoja webu plne dostačujúci. Pozor však na obmedzenia (webserver napríklad využíva pri spracovaní požiadavok jediný jednovláknový proces) a vstavaný webserver používajte len na vývoj a testovacie účely. Na spustenie servera môžete použiť artisan príkaz

php artisan serve

Ak chcete používať o niečo robustnejšie riešenie, môžete skúsiť Valet (osobne sa mi osvedčil najviac), alebo virtuálny Homestead, ktorý je však už trochu tažším kalibrom a na môj vkus spotrebuje priveľa pamäte.

Konfigurácia

Konfiguračné súbory sa nachádzajú v adresári config. Niekoľko konštánt je už vytiahnutých do .env súboru nachadzjúceho sa v koreňovom adresári projektu, kde je možné konfigurovať konštanty v závislosti od prostredia – čo je mimochodom veľmi praktická vec. Odporúčam všetky konfiguračné konštanty, ktoré sú závislé od použitého prostredia (testovanie, produkcia, …) nastavovať v tomto súbore a mať ich tak na jednom mieste.

V rámci konfigurácie skontrolujte práva adresárov storage a bootstrap/cache. Webový server by mal byť schopný do uvedených adresárov zapisovať. Aplikačný kľúč by mal byť vygenerovaný vo vašom .env súbore. Ak tam z nejakého dôvodu nie je, použite príkaz

php artisan key:generate

Tento kľúč je veľmi dôležitý z bezpečnostného hľadiska. Používa sa na šifrovanie session a ďalších kritických dát.

Webserver

Dôležité je nakonfigurovať web root vášho web servera do adresára public, kde sa nachádza front controller. Ak bude web server hľadať súbor index.php v koreňovom adresári projektu, aplikácia pochopiteľne nebude fungovať.

V prípade, že používate Apache, uistite sa, že máte povolény mod_rewrite. Ak máte problém s defaultným .htaccess súborom, skúste alternatívu z dokumentácie.

Všetko pripravené?

Ak inštalácia prebehla v poriadku a vy ste správne nakonfigurovali web server, mali by ste vidieť defaultnú bielu stránku s odkazmi na dokumentáciu a pod.

Ak sa vám táto stránka zobrazuje, gratulujem. Zvládli ste inštaláciu a môžete sa pustiť do vývoja aplikácie.

V prípade, že sa objavila chyba, skontrolujte vyššie uvedené body, alebo napíšte na fórum.

V ďalšom blogu si povieme viac o routingu v Laraveli.