4. díl - Propojení kontroleru a pohledu

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

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

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.itnetwork.cz" target="_blank">itnetwork.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 2503x (6.35 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP

 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
17 hlasů
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.
Miniatura
Předchozí článek
Směrovač (router)
Miniatura
Následující článek
Kontaktní formulář
Aktivity (2)

 

 

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

Avatar
Martin Konečný (pavelco1998):10.11.2015 22:16

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
Go hard or go home!
Avatar
jAkErCZ
Člen
Avatar
jAkErCZ:4.1.2016 21:18

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.1.2016 21:18
Pokud něčeho chceš dosáhnout, musíš si za tím jít.
Avatar
dusekpetrcb
Člen
Avatar
dusekpetrcb:7.2.2016 20:14

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  +1 7.2.2016 20:14
Avatar
Štefan
Člen
Avatar
Štefan:17.7.2016 20:49

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.7.2016 20:49
Avatar
Štefan
Člen
Avatar
Odpovídá na Štefan
Štefan:18.7.2016 10:14

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.7.2016 10:14
Avatar
gold604
Člen
Avatar
gold604:19. února 21:39

Zdravím, asi to bude veľmi hlúpa otázka, ale čo robí presnejšie tento riadok?

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

Nemohlo by sa to dať do index.php?

 
Odpovědět 19. února 21:39
Avatar
IT Man
Redaktor
Avatar
Odpovídá na gold604
IT Man:19. února 22:24

Pokud nechceš psát zbytečně hodně věcí navíc, tak ne, nemohlo. Hned nad tím totiž načítáš data o tom kontroleru, která se ti poté také budou hodit. :)

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.

Editováno 19. února 22:24
Odpovědět 19. února 22:24
Usmívej se, zítra už tvůj kód nemusí fungovat!
Avatar
gold604
Člen
Avatar
gold604:23. února 16:23

Čo je to vnorený kontroler? Ako si ich vytvorím viac?

 
Odpovědět 23. února 16:23
Avatar
michal.smatlak:30. března 18:01

Zdravím, mám menší problém. Idem presne podla tutorialu ale keď zadám localhost/chyba tak sa síce zobrazí chybová stránka ale v celom texte chýbajú znaky ako: á,é,ž,í. Mám tam mb_internal_en­coding("UTF-8"); aj <html lang="sk-SK">, vlastne mám to presne podla tutorialu ale nefunguje to. poraďte mi prosím v čom môže byť chyba. Za všetky rady vopred ďakujem.

 
Odpovědět 30. března 18:01
Avatar
Ondřej Pech
Člen
Avatar
Ondřej Pech:4. května 17:11

Ahoj, co bych měl udělat, kdybych chtěl pro učité stránky použít jinou výchozí šablonu (jinou než rozlozeni.phtml) tipicky nějake pomocné stránky, na kterých nebudu chtít menu ani patičku. Nebo prostě stránku, která nezapadá do mého konceptu, třeba ji načítám v nějakém modalu přes iframe (nějaká reklama a pod.)
resp. chtěl bych načíst jen pohled ale ne až v tom rozlozeni.phtml Díky :)

 
Odpovědět 4. května 17:11
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 116. Zobrazit vše