Pouze tento týden sleva až 80 % na e-learning týkající se C# .NET. Zároveň využij akce až 50 % zdarma při nákupu e-learningu. 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í.
Slevovy týden 3/50

Lekce 1 - Popis MVC architektury

Vítejte u prvního dílu seriálu, ve kterém si postupně vytvoříme plně objektový redakční systém v PHP. Budeme ctít tzv. MVC architekturu, kterou si vysvětlíme v dnešním úvodním článku. Z následujících dílech naprogramujeme web s hezkými URL, přihlašováním, WYSIWYG editorem a kontaktním formulářem. Vytvoříme také několik užitečných tříd, aby se další funkčnosti do webu jednoduše přidávaly.

Jsem vždy udiven obrovskou velikostí zdrojových kódů třetích stran, když jdou věci řešit jednoduše. Náš kód bude minimalistický a celý systém bude obsahovat několik třídiček, které budou velmi krátké.

Seriál počítá se základy objektově orientovaného programování v PHP.

MVC architektura

MVC je velmi oblíbený architektonický vzor, který se uchytil zejména na webu, ačkoli původně vznikl na desktopech. Je součástí populárních webových frameworků, jakými jsou např. Zend nebo Nette pro PHP, Ruby On Rail pro Ruby nebo MVC pro ASP .NET. Osobně si bez něj (nebo nějakého podobného principu) nedokáži představit složitější web.

Princip

Základní myšlenkou MVC architektury je oddělení logiky od výstupu. Řeší tedy problém tzv. "špagetového kódu", kdy máme v jednom souboru (třídě) logické operace a zároveň renderování výstupu. Soubor tedy obsahuje databázové dotazy, logiku (např. PHP operace) a různě poházené HTML tagy. Vše je zamotané do sebe jako špagety. Určitě jste to někde viděli, půjčím si nějaký zdroják z prvních PHP tutoriálů na ukázku:

// Tento kód je jak by náš projekt neměl vypadat
$vysledek = mysql_query("select * from otazky", $spojeni);
if (!mysql_num_rows($vysledek))
    echo '<p>Zatím tu žádnou anketu nemáme.</p>';
else
{
    echo '<ul>';
    while ($radek = mysql_fetch_array($vysledek))
    if ($vybranaanketa == $radek['kodankety'])
        echo '<li>' . $radek['kodankety'] . ': ' . $radek['otazka'] . ' (aktuálně vybraná)</li>';
    else
        echo '<li><a href="tvorbaanket.php?vybranaanketa=' . $radek['kodankety'] . '">'
        .$radek['kodankety'] . ': '
        .$radek['otazka'] . '</a></li>';
    echo '</ul>';
}

Kód se samozřejmě špatně udržuje, natož rozšiřuje. Je špatně highlightovaný, protože si s ním IDE neví rady, HTML není správně naformátováno, ztrácíme se v jeho stromové struktuře. Naším cílem je, aby zdrojový kód s logikou vypadal jako zdrojový kód (např. PHP) a výstup vypadal jako HTML stránka s co nejmenší příměsí dalšího kódu. Kód výše by se tedy rozdělil do 2 souborů (HTML šablony a PHP skriptu), ideálně ještě s použitím dalších tříd. Již brzy v seriálu uvidíme, jak kód MVC aplikace vypadá.

Komponenty

Celá aplikace je rozdělena na komponenty 3 typů, hovoříme o Modelech, View (pohledech) a Controllerech (kontrolerech), od toho MVC. Neexistuje žádná striktní definice MVC architektury a tak se můžete setkat s více výklady. Je dost možné, že to, co zde popisuji, je architektura MVP (nebudu rozebírat) nebo dokonce něco mezi. Co člověk, to názor, co framework, to jiný přístup. Důležitý je však základní princip, tedy rozdělení hlavních rolí těchto 3 komponent.

Komponenty jsou samozřejmě třídy, které mohou být odděděné z abstraktních předků, jen view je většinou jen jako HTML šablona. Pojďme si jednotlivé komponenty nejprve popsat.

Model

Komponenta model z MVC architektury Model obsahuje logiku a vše, co do ní spadá. Mohou to být výpočty, databázové dotazy, validace a podobně. Model vůbec neví o výstupu. Jeho funkce spočívá v přijetí parametrů zvenku a vydání dat ven. Zdůrazním, že parametry nemyslím URL adresu ani žádné jiné parametry od uživatele. Model neví, odkud data v parametrech přišla a ani jak budou výstupní data zformátována a vypsána.

Budeme programovat bez tzv. ORM (objektově relačního mapování), jelikož PHP defaultně nic takového nemá a hotová řešení jsou zbytečně těžkopádná. Navíc PHP obsahuje skvělé datové struktury, které s dynamickým typováním nahradí vše potřebné. Pokud vám zkratka ORM nic neříká, vůbec to nevadí. Budeme využívat principu manažerů, logika aplikace tedy bude rozdělena např. mezi manažer ManazerUzivatelu, ManazerClanku a tak podobně. Ty obsahují metody k výběru potřebných údajů z databáze nebo k jejich modifikaci, např. metodu k výběru přezdívky a informací o uživateli při vypsání jeho profilu. Jinou metodou bychom vybírali otisk hesla z databáze, abychom ověřili přihlášení, další by nám vrátila třeba články uživatele. V manažeru zároveň najdeme pomocné metody k práci s uživateli, např. ono ověření správné délky a znaků hesla. Logika se nemusí týkat jen databáze, patří sem i ostatní věci jako validace (např. ověření správné délky a formátu zadaného hesla).

Nyní máme představu, co model vykonává, pojďme se podívat na pohled.

Pohled

Komponenta view z MVC architektury Pohled (View) se stárá o zobrazení výstupu uživateli. Nejčastěji se jedná o phtml šablonu, obsahující HTML stránku a tagy nějakého značkovacího jazyka, který umožňuje do šablony vkládat proměnné, případně provádět iterace (cykly) a podmínky. Opět zachováme maximální jednoduchost a stejně jako tomu bylo s ORM, i zde si vystačíme pouze s tím, co nám nabízí PHP. Pro šablony se často používají speciální značkovací jazyky (např. Smarty). Pro PHP nemá ale příliš velký smysl používat značkovací jazyk, jelikož je samo značkovacím jazykem a umožňuje takový styl zápisu kódu, aby struktura HTML stránky zůstala zachována.

Pohledů máme mnoho, např. pro funkcionalitu s entitou uživatele: uzivatel_registrace, uzivatel_prihlaseni, uzivatel_profil a podobně. Pohled uzivatel_profil je ale již společný všem uživatelům a jsou do něj posílána různá data, vždy podle toho, koho zrovna zobrazujeme. Tato data jsou poté dosazena do HTML elementů šablony.

Pohledy lze samozřejmě vkládat do sebe, abychom se neopakovali (šablona s rozložením stránky, šablona s menu a šablona článkem).

View není jen šablona, ale zobrazovač výstupu. Obsahuje tedy minimální množství logiky, která je pro výpis nutná (např. kontrola, zda si uživatel vyplnil prezdívku před jejím vypsáním nebo cyklus s komentáři, které se vypisují).

View podobně jako Model vůbec neví, odkud mu data přišla, stará se jen o jejich zobrazení uživateli.

Kontroler

Komponenta controller z MVC architektury Kontroler je nyní onen chybějící prvek, který osvětlí funkčnost celého vzoru. Jedná se o jakéhosi prostředníka, se kterým komunikuje uživatel, model i pohled. Drží tedy celý systém pohromadě a komponenty propojuje. Jeho funkci pochopíme z ukázky životního cyklu stránky. Opět existuje mnoho různých přístupů, nejčastěji má každá entita jeden kontroler, máme tedy UzivatelKontroler, ClanekKontroler a tak podobně.

Životní cyklus stránky

Životní cyklus zahajuje uživatel, který zadá do prohlížeče adresu webu a parametry, kterými nám sdělí, kterou podstránku si přeje zobrazit. Budeme chtít zobrazit detail uzivatele s id 15. Udělejme si ukázku URL adresy:

http://www.domena.cz/uzivatel/detail/15

Požadavek jako první zachytí tzv. směrovač (router). Ten podle parametrů pozná, který kontroler voláme. Jistě bychom vymysleli mnoho způsobů, jak jméno kontroleru poznat. Udržujme maximální jednoduchost a vypusťme tzv. manuální routování, název kontroleru jednoduše uvedeme jako 1. parametr v URL. Zde je tedy zavolán kontroler UzivatelKontroler, kterému jsou předány 2 parametry "detail" a 15.

Daný kontroler podle parametrů pozná, co se po něm chce, tedy že má zobrazit detail uživatele. Zavolá model, který uživatele vyhledá v databázi a vrátí jeho údaje. Dále zavolá další metodu modelu, která např. vypočítá věk uživatele. Tyto údaje si kontroler ukládá do proměnných. Nakonec vypíše pohled (view). Název pohledu poznáme podle akce, kterou provádíme. Pohledu jsou předány proměnné s příslušnými daty. Kontroler tedy poslechl uživatele, obstaral podle parametrů dotazu data od modelu a předal je pohledu.

Pohled přijme data od kontroleru a vloží je do připravené šablony. Hotová stránka je zobrazena uživateli, který často o celé této kráse ani netuší :)

Celou situaci můžeme znázornit diagramem:

MVC architektura

Získali jsme tedy oddělení logiky od výstupu, view jsou jako HTML, modely zas v našem skriptovacím jazyce (např. v PHP). Dosáhli jsme přehlednosti kódu, který je logicky rozčleněný.

MVC architektura nám usnadňuje i myšlení při vývoji projektu. Když píšeme logiku, patří do modelu, formátování a stylování výstupu řešíme v šabloně, to co uživatel chce z parametrů zjišťujeme v kontroleru. 3 různé problémy na 3 různých místech, oddělené tak, aby do sebe nezasahovaly a nedělaly nám vývoj složitější.

Příště začneme s inicializací systému a směrovačem v lekci .htaccess, autoloader a obecný kontroler.


 

Všechny články v sekci
MVC - Jednoduchý redakční systém v PHP objektově
Přeskočit článek
(nedoporučujeme)
.htaccess, autoloader a obecný kontroler
Článek pro vás napsal David Čápka
Avatar
Uživatelské hodnocení:
155 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 13 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity