4. díl - Propojení kontroleru a pohledu

PHP MVC Propojení kontroleru a pohledu American English version English version

V minulém dílu našeho seriálu tutoriálů pro jednoduchý objektový redakční systém v PHP jsme si vytvořili směrovač, tedy router. Skončili jsme tím, že z URL adresy poznáme jméno třídy kontroleru a jeho další parametry. Dnes systém částečně zprovozníme a zobrazíme si jednoduchý článek.

Pohledy

Začněme s něčím jednoduchým a připravme si 2 pohledy. Ty následně propojíme s kontrolery a konečně si něco zobrazíme.

Rozložení stránky

Jak víme, kontroler má v sobě uložený název pohledu, který uživateli zobrazí. SmerovacKontroler bude zobrazovat pohled s rozložením stránky, to bude obsahovat hlavičku, navigační menu, patičku a vše kolem stránky. Co obsahovat nebude bude ten hlavní obsah, který se sem vloží jako pohled z vnořeného kontroleru.

Jelikož v tomto seriálu nemá smysl popisovat HTML a CSS, připravil jsem pro vás jednoduchou šablonu pro rozložení stránky. Ve složce pohledy si vytvoříme soubor rozlozeni.phtml. Do něj vložíme následující kód:

<!DOCTYPE html>
<html lang="cs-cz">
        <head>
                <base href="/localhost" />
                <meta charset="UTF-8" />
                <title><?= $titulek ?></title>
                <meta name="description" content="<?= $popis ?>" />
                <meta name="keywords" content="<?= $klicova_slova ?>" />
                <link rel="stylesheet" href="style.css" type="text/css"/>
        </head>

        <body>
                <header>
                        <h1>DevbookMVC - ukázkový web</h1>
                </header>

                <nav>
                        <ul>
                                <li><a href="clanek/uvod">Úvod</a></li>
                                <li><a href="clanek">Články</a></li>
                                <li><a href="kontakt">Kontakt</a></li>
                        </ul>
                </nav>
                <br clear="both" />

                <article>

                </article>

                <footer>
                        <p>Ukázkový tutoriál pro jednoduché MVC z programátorské sociální sítě
                        <a href="http://www.devbook.cz" target="_blank">devbook.cz</a>.</p>
                </footer>
        </body>
</html>

Na zdrojovém kódu si všimneme několika věcí. Zaprvné je to z 99% HTML, je hezky přehledný a dobře strukturovaný. Také používám HTML 5 tagy, ale to by dnes již mělo být samozřejmostí.

V hlavičce nalezneme tag <base>, ten určuje kořenovou složku webu. Ta je důležitá např. pro obrázky, soubory css, ikony atd. Jelikož používáme hezká URL s lomítky, prohlížeč by si myslel, že jsme zanořeni v nějakých složkách. Takto mu explicitně sdělíme, že chceme pracovat z kořene. Na produkci si localhost musíte přepsat na absolutní URL adresu webu, tedy např.: "http://www.do­mena.cz/". Teoreticky by měla fungovat i hodnota "/", ale jeden nejmenovaný prohlížeč s modrým "e" to neumí.

Všimneme si PHP direktiv v hlavičce stránky:

<title><?= $titulek ?></title>
<meta name="description" content="<?= $popis ?>" />
<meta name="keywords" content="<?= $klicova_slova ?>" />

Těmi vkládáme proměnné z kontroleru (přesněji z jeho pole $data). V žádném případě nebudeme v šabloně vkládat HTML do PHP, naopak vkládáme minimum PHP do HTML a to ještě tak, aby zůstala zachována HTML struktura. Jistě víte, že:

<?= $promenna ?>

je zkrácený zápis tohoto:

<?php echo $promenna; ?>

PHP má mnoho takovýchto syntaktických zlepšováků pro šablony a proto si s ním krásně vystačíme bez dalšiho šablonovacího jazyka. Často zaměňuji termíny šablona a pohled, myslím tím totéž, jelikož v našem MVC je pohled realizován phtml šablonou.

Poslední zajímavou věcí je tělo článku, tedy mezi tagy <article>. Všimněte si, že je zatím prázdné, časem právě sem vypíšeme pohled vnořeného kontroleru.

Chyba

Jako další šablonu vytvoříme stránku chybovou. Zobrazí se v případě, že uživatel zadal nesmyslnou URL adresu. Její HTML kód bude následující:

<h1>Chyba 404</h1>
<p>Požadovaná stránka nebyla nalezena, zkontrolujte prosím URL adresu</p>

Styl

Co by to bylo za web bez stylu? Připravil jsem samozřejmě i ten. V kořenové složce s webem vytvoříme soubor style.css, jeho obsah bude následující:

body {
        font-family: verdana;
        font-size: 14px;
        width: 900px;
        margin: 0 auto;
}

h1 {
        text-align: center;
        color: #444444;
        text-shadow: 3px 3px 3px #aaaaaa;
}

footer {
        font-size: 11px;
        text-align: center;
        padding-top: 20px;
}

article {
        text-shadow: 3px 3px 3px #aaaaaa;
}

nav ul {
        list-style-type: none;
}

nav li {
        float: left;
        margin-right: 15px;
}

nav a {
        background: #6FA4F8;
        color: white;
        padding: 5px 10px;
        border-radius: 10px;
        text-decoration: none;
        border: none;
        cursor: pointer;
}

nav a:hover {
        background: #2976f8;
        color: #EEEEEE;
        text-decoration: none;
}

Až na pár CSS3 vlastností na něm není nic zajímavého.

Výpis pohledů

Pohledy máme založené, kontrolery máme založené, pojďme aplikaci konečně zprovoznit.

Přesuneme se do SmerovacKontroler, kde v metodě zpracuj() vymažeme kontrolní výpisy z minula a budeme v ní pokračovat. Pokud není zadán žádný kontroler (první parametr URL adresy je prázdný nebo úplně chybí), přesměrujeme na úvodní článek. Ten sice ještě neexistuje, nicméně s ním již můžeme počítat.

public function zpracuj($parametry)
{
        $naparsovanaURL = $this->parsujURL($parametry[0]);

        if (empty($naparsovanaURL[0]))
                $this->presmeruj('clanek/uvod');
        $tridaKontroleru = $this->pomlckyDoVelbloudiNotace(array_shift($naparsovanaURL)) . 'Kontroler';

Pokud skript pokračuje dál, máme název třídy kontroleru a podíváme se, zda opravdu existuje. Pokud ano, vytvoříme její instanci. Pokud ne, přesměrujeme na chybovou stránku.

if (file_exists('kontrolery/' . $tridaKontroleru . '.php'))
        $this->kontroler = new $tridaKontroleru;
else
        $this->presmeruj('chyba');

Máme instanci vnořeného kontroleru tam, kde jsme ji chtěli mít. Nyní na vnořeném kontroleru zavoláme také metodu zpracuj() a necháme ho provést nějakou jeho logiku, později to např. u článku bude jeho vyhledání v databázi. Přesněji kontroler zavolá logiku v modelu, ale nepředbíhejme.

$this->kontroler->zpracuj($naparsovanaURL);

Zbývá nastavení pohledu směrovače, tedy šablony s rozložením webu.

Vytvoříme si několik proměnných pro šablonu. Již víme, že jsme v šabloně použili $titulek, $klicova_slova a $popis. Také víme, že proměnné šabloně předáme jako klíče v poli $this->data[]. Jako hodnoty do šablony vložíme vždy titulek, popis a klíčová slova, která má vložený kontroler. Kód bude vypadat takto:

$this->data['titulek'] = $this->kontroler->hlavicka['titulek'];
$this->data['popis'] = $this->kontroler->hlavicka['popis'];
$this->data['klicova_slova'] = $this->kontroler->hlavicka['klicova_slova'];

Nakonec zbývá nastavit pohled, to uděláme jednoduše dosazením názvu souboru s pohledem do atributu $pohled:

// Nastavení hlavní šablony
$this->pohled = 'rozlozeni';

SmerovacKontroler je hotový.

ChybaKontroler

Vytvořme si konečně náš první kontroler pro nějakou součást webu. Bude se samozřejmě jednat o chybovou stránku. Ve složce kontrolery založíme ChybaKontroler.php s následujícím obsahem:

class ChybaKontroler extends Kontroler
{
    public function zpracuj($parametry)
    {
        // Hlavička požadavku
        header("HTTP/1.0 404 Not Found");
        // Hlavička stránky
        $this->hlavicka['titulek'] = 'Chyba 404';
        // Nastavení šablony
        $this->pohled = 'chyba';
    }
}

Kontroler odešle prohlížeči hlavičku, aby věděl, že je na chybové stránce. Jinak nedělá nic jiného, než že podstránce nastaví titulek a šablonu.

Máme hotovo. To bylo rychlé, že? Podobným způsobem budeme nyní do systému přidávat další součásti.

Zadrátování

A jsme ve finále. Do index.php připojme za volání metody zpracuj() na směrovači také metodu vypisSablonu(). Zde je opět krásně vidět, jak jsou logika a výpis odděleny na 2 samostané úlohy.

$smerovac->vypisPohled();

Když nyní zadáme libovolnou URL adresu, budeme přesměrování na adresu "chyba", kde směrovač zavolá ChybaKontroler. Uvidíme, že zafungoval směrovač a vypsal nám šablonu.

Devbook MVC framework v PHP

Šablona vnořeného kontroleru (ChybaKontroleru) vypsaná není, pojďme to napravit. Na prázdné místo v tagu <article> v šabloně rozlozeni.phtml vložme šablonu vnořeného kontroleru. Jelikož šablona se zpracovává v SmerovacKontroler, můžeme jednoduše přistoupit k vnořenému kontroleru jako k instanční proměnné. Toto do pohledů úplně nepatří, ale v rozložení je to nutné:

<?php $this->kontroler->vypisPohled(); ?>

Výsledek:

Devbook MVC framework v PHP

Konečně něco funkčního, i když je to zatím jen chybová stránka :) Příště si do systému přidáme jednoduchý kontaktní formulář.


 

Stáhnout

Staženo 2244x (6.35 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP

 

  Aktivity (1)

Článek pro vás napsal David Čápka
Avatar
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.

Jak se ti líbí článek?
Celkem (15 hlasů) :
4.599994.599994.599994.599994.59999


 


Miniatura
Předchozí článek
Směrovač (router)
Miniatura
Následující článek
Kontaktní formulář

 

 

Komentáře
Zobrazit starší komentáře (101)

Avatar
loading84
Člen
Avatar
loading84:

Mam dotaz, jestli chápu dobře, tak tenhle kus kódu udělá.

$tridaKontroleru = $this->pomlckyDoVelbloudiNotace(array_shift($naparsovanaURL)) . 'Kontroler';

ze promena

$naparsovanaURL

prijde o prvni prvek pole... a pak zbyde jenom prvek pole s indexem 1

 
Odpovědět 10.11.2015 20:41
Avatar
Odpovídá na loading84
Martin Konečný (pavelco1998):

Se podívej do manuálu, co array_shift() dělá :D Odebere první prvek pole a vrátí ho (tzn. se v tomto případě použije jako parametr metody).

 
Odpovědět 10.11.2015 20:51
Avatar
loading84
Člen
Avatar
Odpovídá na Martin Konečný (pavelco1998)
loading84:

To jsem pochopil, akorát jsem myslel že to nebude fungovat takhle:

<?php
$stack = array("orange", "banana", "apple", "raspberry");
$fruit = array_shift($stack);
print_r($stack);
?>

output

Array
(
[0] => banana
[1] => apple
[2] => raspberry
)
ale takkhle

<?php
$stack = array("orange", "banana", "apple", "raspberry");
$fruit = array_shift($stack);
print_r($stack);
?>

output

Array
(
[0] => orange
[1] => banana
[2] => apple
[3] => raspberry
)

s tím že

$fruit = 'orange';
 
Odpovědět 10.11.2015 21:00
Avatar
Odpovídá na loading84
Martin Konečný (pavelco1998):

No $fruit = 'orange', protože to byl první prvek v poli, který se z něj odstranil a vrátil (zde uložil do proměnné $fruit).
Jestli chceš jen získat první prvek v poli, stačilo by $fruit = $stack[0];

 
Odpovědět 10.11.2015 21:36
Avatar
loading84
Člen
Avatar
Odpovídá na Martin Konečný (pavelco1998)
loading84:

Já už vím. Ale díky. Teď řeším tenhle článek http://www.itnetwork.cz/…eceni-sablon . Vůbec tomu nerozumím. Nebo spíše myšlence rozumím, ale v kódu se ztrácím.

 
Odpovědět 10.11.2015 21:39
Avatar
Odpovídá na loading84
Martin Konečný (pavelco1998):

Tam metoda osetri() ochrání proměnnou proti XSS. Když se tam hodí pole, metoda projede všechny jeho prvky (a pokud jsou tam další pole, tak rekurzivně) a ošetří je postupně.
Metoda extract() pak z klíčů pole udělá proměnné (viz php.net), které můžeš použít v šabloně

 
Odpovědět 10.11.2015 22:16
Avatar
jAkErCZ
Člen
Avatar
jAkErCZ:

Proč mě to háže Internal error 500 a když mrknu do logu háže mi to chybu na

PHP Fatal error:  Call to undefined method SmerovacKontroler::presmeruj() in /home/users/jakercz/inspire-gaming.g6.cz/web/kontrolery/SmerovacKontroler.php on line 47

Tak to nechápu... co s tím je špatně..

Odpovědět 4. ledna 21:18
Pokud něčeho chceš dosáhnout, musíš si za tím jít.
Avatar
dusekpetrcb
Člen
Avatar
dusekpetrcb:

Ahoj, mám zvídavý dotaz. Errorovou stránku mám na error.phtml s kontrolerem ErrorController. Všechno funguje, jak má, až na jednu výjimku. Když jsem uživatel-filuta a zadám localhost/error/pa­rametr. Potom se to zboří a jde to na klasickou chybu 404 Objekt nenalezen přímo v rámci prohlížeče (mimo moje rozhraní). A když zadám localhost/error/ (s lomítkem na konci), jde to na chybu 403 Přístup odmítnut. Asi tam mám někde chybu, nepřipadá mi to jako očekávané a správné chování. Má někdo nápad, čím by to mohlo být?

Díky.

 
Odpovědět 7. února 20:14
Avatar
Štefan
Člen
Avatar
Štefan:

Zdravím.
Ak som dobre pochopil, tak na to aby sa zmenil "pohlad" potrebujem mat príslušný kontroler. Čo ma však zaráža a trápi dosť dlho je táto vec: tlačidlo "Úvod" som premenoval na Domov (aj samotný odkaz v kóde som pozmenil), v súbore SmerovacKontroler som prepísal riadok, v ktorom sa má určovať "pohlad", ktorý sa načíta ak nie sú zadané žiadne parametre ->

if (empty($naparsovanaURL[0]))
        $this->presmeruj('domov');

Samozrejme som vytvoril príslušný .phtml súbor a DomovKontroler, v kt. mám uvedený príkaz na zmenenie pohľadu ->

<?php
class DomovKontroler extends Kontroler
{
    public function spracuj($parametre)
    {
        $this->hlavicka['titulok'] = 'Domov';
        $this->pohlad = 'domov'
    }
}

Problém je ten, že po spustený alebo kliknutí na tlačidlo "Domov" mi neustále stránka vypíše chybu 404 :-(
Prosím navrhnite nejaké riešenie alebo mi aspoň poskytnite radu.
Za akúkoľvek odpoveď vopred ďakujem.

 
Odpovědět 17. července 20:49
Avatar
Štefan
Člen
Avatar
Odpovídá na Štefan
Štefan:

OK už mi to funguje, chyba bola v syntaxe... Pôvodne som mal tento riadok napísaný takto:

$this->pohlad = 'domov'

A po dlhom rozmýšľaní mi napadlo, že mi tam dosť dôležitý znak -> ; :-D
Preto som to upravil do konečnej podoby:

$this->pohlad = 'domov';
 
Odpovědět 18. července 10:14
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 111. Zobrazit vše