Tvorba MVC Frameworku
V tomto článku sa dozvieťe čo je to MVC Pattern, ako pracuje a ako vytvoriť MVC Framework.
MVC Pattern
MVC (Model View Controller) Pattern je softwarová architektúra, ktorá rozdeľuje dátovy model, užívateľské rozhranie a riadiacu logiku do troch nezávislých na sebe komponentov.

Krok 1.
V tomto kroku si vytvoríme súbor .htaccess ktorý nám bude presmerovávať linky na indexovú stránku frameworku:
/.htaccess
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
Krok 2.
Teraz si vytvoríme indexovú stránku frameworku ktorá bude spúštať naše aplikácie.
/index.php
<?php
// definujeme si root webu
define("BASE_PATH", dirname(realpath(__FILE__))."/");
// inkludujeme framework
include_once BASE_PATH . "framework.php";
// spustíme framework
$application = new Framework();
// a načítame controller
$application->loadController();
?>
Krok 3.
Konečne sme pri tom frameworku.
Základ
/framework.php
<?php
if(!defined("BASE_PATH")) exit("No direct script access allowed");
// definujeme triedu Framework
class Framework
{
Error function
// definujeme metódu show_error
public function show_error()
{
die("404 Error - File not found.");
}
Model
// definujeme metódu loadModel
public function loadModel( $model )
{
// pridáme koncovku _model
$model .= "_model";
// odkaz na model
$model_file = BASE_PATH . "application/models/".$model.".php";
// ak model neexistuje
if(!file_exists($model_file))
{
// zobrazí sa chyba
$this->show_error();
} else {
// inak inkludneme model
include_once $model_file;
// a vytvorí object s týmto modelom
$this->$model = new $model;
}
}
View
// definujeme metódu loadView
public function loadView($view, $view_data = array())
{
// pridáme koncovku _view
$view .= "_view";
// odkaz na view
$view = BASE_PATH . "application/views/".$view.".php";
// ak existujú dáta(array) a nieje prádzny
if(is_array($view_data) && count($view_data) > 0)
{
// tak klúče arrayu sa prepíšu na premennu
extract($view_data, EXTR_PREFIX_SAME, "wddx");
}
// ak view neexistuje
if(!file_exists($view))
{
// zobrazí sa chyba
$this->show_error();
} else {
// inak inkludneme view
include_once $view;
}
}
Controller
// definujeme metódu loadController
public function loadController()
{
// rozbijeme uri
$uri = preg_split("[\\/]", getenv("REQUEST_URI"), -1, PREG_SPLIT_NO_EMPTY);
$cmv = array(
// definujeme defaultný controller
"controller" => "welcome",
// definujeme metódu ktorá sa zavolá ak nieje zadaná metóda
"method" => "index",
// array klúč do ktorého sa uložia dáta, ak nejaké budú
"vars" => NULL);
// ak je nejaké uri
if(count($uri) > 0)
{
// zistíme a zapíšeme controller
$cmv['controller'] = $uri[0];
// potom vymažeme zbytočné miesto
unset($uri[0]);
// ak ešte existuje uri tak to bude metóda
if(isset($uri[1]))
{
// zistíme a zapíšeme metódu
$cmv['method'] = $uri[1];
// potom vymažeme zbytočné miesto
unset($uri[1]);
}
// ak stále existujú uri, tak to budú premenné
if(isset($uri))
{
foreach($uri as $key => $value)
{
// zapíšeme premenné do premennej vars
$cmv['vars'][] = $value;
}
// potom vymažeme zbytočné miesto
unset($uri);
}
}
// odkaz na controller
$controller = BASE_PATH . "application/controllers/".$cmv['controller'].".php";
// ak controller neexistuje
if(!file_exists($controller))
{
// zobrazí sa chyba
$this->show_error();
} else {
// inak inkludneme controller
include_once $controller;
// spustíme controller
$controller = new $cmv['controller'];
// ak existuje metóda
if(method_exists($controller, $cmv['method']))
{
// tak spustíme aj tú,s dátami
$controller->{$cmv['method']}($cmv['vars']);
}
}
}
Krok 4.
Prvý controller!
Prvý controller si môžme urobiť nejaký jednoduchý napr. na výpis textu.
POZOR! Názov triedy v controlleri sa musí volať tak isto ako samotný controller!
/application/controllers/welcome.php
<?php
if(!defined("BASE_PATH")) exit("No direct script access allowed");
// vytvoríme triedu s názvom controlleru,teda welcome.php => welcome
class welcome extends Framework
{
// metóda ktorá sa zavolá ak nebude zadaná metóda
function index()
{
// načítame view
$this->loadView("index");
}
// metóda test s uri a modelom
function test($args="")
{
// načítame model names
$this->loadModel("names");
// načítame dáta s modelu
$data = $this->names_model->getNames();
// a zapíšeme uri
$data['uri'] = $args;
// načítame view
$this->loadView("hello", $data);
}
}
Prvý model
/application/models/names_model.php
<?php
if(!defined("BASE_PATH")) exit("No direct script access allowed");
// vytvoríme triedu s názvom modelu teda names_model.php => names_model
class names_model extends Framework
{
// metóda ktorá vypíše dáta
function getNames()
{
$names = array(
"nick" => "nipid",
"firstname" => "Andrej",
"surname" => "Mihaliak");
return $names;
}
}
Prvý controller - views
/application/views/index_view.php
<!doctype html> <html> <head> <title>Welcome!</title> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta name="description" content=""> <meta name="keywords" content=""> </head> <body> Welcome in framework! </body> </html>
/application/views/hello_view.php
<!doctype html>
<html>
<head>
<title>Hello!</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="description" content="">
<meta name="keywords" content="">
</head>
<body>
Hello <?=$nick;?> <small>(<?=$firstname;?> <?=$surname;?>)</small>.<br/><br/>
<?php
if(isset($uri))
{
echo "URI:<br/><pre>";
print_r($uri);
echo "</pre>";
}
?>
</body>
</html>
Celý framework si môžete stiahnuť TU.
26 komentárov k článku:
Komentovať môžu iba prihlásení
Zaregistruj sa cez bezplatnú registráciu alebo použi login cez Facebook (FB Connect)
Prihlás sa tu, ak už máš profil na Zajtra.sk:
Velmi pekne dakujem, exceletne napisane, sarmantne a lahkopochopitelne nakodovany cms .
A neviem co maju ini vyhrady proti short tags ste normalni? toto neni produkcny cms, aj keby to napisal v ASP a dal nadpis PHP cms ide o princip ako to spravit.
shorttagy su v tutorialoch tohto typu ovela prehladnejsie.
tento clanok je velmi dobry, normalne sa programatori do velkych php frameworkov ani nepustia, kvoli zlozitosti.
Dnes uz moc nedava zmysel pisat clanky typu "sprav si vlastny PHP framework". Na vyucovanie OOP v PHP je vhodnejsie zvolit prave existujuci zabehnuty FW a riesit v nom nejaku vec "zo zivota vyvojara".
Serialy maju ak teda maju byt seriove, musia prezentovat kod, ktory bude citatel do buducna sam rozsirovat. A to mam velke pochybnosti, ze "vlastny PHP framework" je na toto vhodny. Je to pre citatela zabity cas, lebo v buducnosti (ked dosiahne urcitu uroven) aj tak switchne na "velky" FW.
@Zdenko Vrabel:
Add1.: mne to prislo ako by tym extendovanim Frameworku chcel povedat ze to patri do package frameworku ale to stacilo napisat do anotacie alebo pouzit php 5.3 namespace ale urcite nie modelom ani controllerom rozsirovat Framework.. to nema nic spolocne ani len logicky, Framework je skor len cieleny nazov na tu skupinu skriptov, ktore tvoria nejaku zakladnu strukturu aplikacie
Add 2.: vacsina frameworkov aspon co poznam jasne oddeluje view od controllera/presentera, modelu (nette, zend, cakephp,...) :) ale to je vlastne jedno :D
Ahoj,
Neda mi nezareagovat na clanok. Podla mojho nazoru ide o dost zvlastny MVC. Priznam sa ze niesom PHPckar ale princip je vsade rovnaky takze par poznamok k tomu:
Add 1. Ak si clanok dava za ciel vysvetlit MVC, tak podla mna ciel nebol splneny. Totizto uz len uvodny obrazok uplne deformuje MVC. Doporucujem GoF Dessign Patterns kde je MVC popisany. Ide o starsiu publikaciu ale myslim ze MVC sa za poslednych 18 rokov nezmenilo. Chapem ze ide o ilustracny clanok ale z neho mi vypliva ze tie kompetencie toho vsetkeho su nejake rozhadzane. Na co narazam. Podla clanku cloveku pride ze napriklad data z DB (skrz nejake DAO) by sa mali teda riesit v Model. To je vsak vec controllera a model by mal byt v podstate len datova struktura (najlepsie immutable). Samozrejme mozno som to len zle vyrozumel z clanku. Doporucoval by som teda ten obrazok aspon znazornit tak ako ma byt plus presne popisat ktora cast je presne za co zodpovedna.
add 2. Celkovo problem u MVC a PHP (ASP a JSP) je ten ze to viewu clovek moze narvat kod a casto ho tam aj narve. Par frameworkov ako Lift a aj vela programatorov to riesi ze na views pouzivaju templates mechanizmy.
Add 3. Priklanam sa k nazoru Andreja Sykoru. Dedicnost je u juniorov akosi zle chapana. Toto je nieco co dodnes nechapem. Kazda knizka o OOP zacina dedicnostou, kazda prednaska zacina dedicnostou. Potom kazdy vsetko riesi cez dedicnost. Ono si to mozno teraz clovek neuvedomi ale neskutocne si zavaris tym, ze vsetko naviazes na jedneho predka. Preco sa pri OOP nespomina golden rule 'Prefer composition over inheritance'? Obzvlast u frameworkov to plati.
Neber to ako utok ale skor ako konstruktivnu kritiku. Sam som implementoval MVC. Nebola to vec ktora mi zabrala 2 tyzdne ale stravil som pol roka len studovanim ako sa veci maju. Urobil som vela chyb a tiez sa mi to zo zaciatku zdalo ako jasna vec.Kazdopadne drzim palce. Zimplementovat MVC nieje lahka zalezitost. Studuj, skusaj, experimentuj, rad sa.
Sorrac za gramatiku.
nie som v MVC moc peceny vareny, no pripojenie na db v controlleri nepotrebujes z toho titulu ze vybery z db by mal managovat vyhradne model. No je to len moj skormny nazor a vlastne chapanie MVC :) Inak vela zdaru v programovani :) clanok ma zaujal hlavne svojou jednoduchostou, ktora niekedy urcitym veciam chyba :)
Andrej, prepáč za kritiku, ale podľa toho, ako si reagoval na výčitky pána Knesla, nemáš vôbec poňatie o princípoch OOP a tým pádom Tvoj článok viac mätie ako pomáha.
Trieda Framework reprezentuje základňu frameworku, akési prostredie, environment, OK. Ako môžeš potom z tejto triedy odvodiť triedu, ktorá reprezentuje model, čiže nástroj na získavanie dát, a controller, čiže nástroj kontrolujúci určitú funkčnú časť aplikácie? To sú 3 úplne iné objekty, ktoré nemôžu mať jedného spoločného predka, pokiaľ sa teda nejedná o nejakú základnú definíciu objektu s pomocnými metódami. (o čo sa v Tvojom prípade nejedná)
Skúsim príklad. Je to ako by si napísal triedu Les, z ktorej si potom odvodil triedy Zviera a Búrka. Tri úplne rozdielne veci.
K ostatným veciam sa nejdem vyjadrovať, pretože práve chyby v návrhu mi prídu ako hlavný problém celého článku.
Ďakujem za ohlasy k článku, je to môj prvý článok čo sa týka oop, je to na zorientovanie sa v oop a mvc patterne.Framework sa dá určite ešte vylepšiť ale myslím si že keď niekto hľadá niečo podobné tak php určite do nejakej znalosti pozná a vie si tam dorobiť poprípade prerobiť určité veci.
@Jiri Knesl:
1) myslel som si to tiež ale ak sa robí framework je veľká pravdepodobnosť že bude pracovať aj z nejakou tou databázou, a preto som ho extendoval aj do controlleru aj do modelu, stačí ak si potom do konštrunktora frameworku dá napojenie do db
2) tento článok ukazuje ako ho urobiť najjednoduchšie čo sa týka toho že by si chcel robiť nejaké triedy ktoré niesu controller tak by sa to dalo určite nejako ochrániť to si možno ukážeme nabudúce :) ak nejaké bude
3) 4) 5) 6) 7) myslím si že k tomu nieje nič dodať každý si predsta môže framework upraviť podľa seba, je to len ukážka ako si ho urobiť nikde nieje písané že ho musí tiež používať :)
8) myslím si že to tam má čo robiť, aj kebyže to máš v nejakom inom adresáry ako je root tak by sa tam mohol kto koľvek dostať,táto podmienka to chrány aby sa k tomu nedostalo nijak inak ako cez indexovú stránku
9) je to môj prvý článok tak dúfam že sa zlepším
BTW: dík za kritiku
ja osobne by som to skor riesil takto: sprintf($lang['welcome'], $nick, $firstname, $lastname);
Ked uz framework, tak poriadne poodelovat jednotlive vrstvy.
bola to len rada, ziadny problem, casto si hosting nevyberas.
co sa tyka prehladnosti (a myslim ze i rychlosti) mam pocit ze to teda neni nic moc ani s nimi, ak to editor vie highlightnut ide to aj takto:
echo "Hello $nick <small>($firstname $surname)</small>";
ad shorttagy.. odporcovia, mate pocit, ze <?php echo 'nieco';?> je lepsie a prehladnejsie nez <?='nieco'?> ? Ja nie. To, ze na niektorych hostingoch su vypnute je pravda, ale do takeho hostingu predsa nepoleziem nie? A shorttagy sa pouzivaju aj tak len vo viewoch (btw aj CI nabada k ich pouzivaniu), takze aky problem?
@Matúš pochybné hostingy so shortagmi nemajú problém, s ich vypnutím som sa naopak stretol na serverovej farme jednej z najväčších internetových spoločností na Slovensku.
Tento kód je úplně špatně.
1) není důvod extendovat třídu framework
2) podstrčím-li do URL název nějaké třídy, která není controller, dostanu 500
3) metody jsou příliš dlouhé
4) není zde žádná štábní kultura, občas je název třídy velký, občas malý
5) volani die() způsobí, že se na kód nedají napsat testy, správně by se měla vyhodit vyjímka, controller by měl mít nějaký dispatch, který ji odchytí
6) není důvod, proč neloadovat modely a controllery přes autoloading
7) extract($view_data, EXTR_PREFIX_SAME, "wddx"); - má zkontrolovat spíš zakázané indexy a vyhodit vyjímku, takhle se člověk nedozví, proč se jeho proměnná nepřevedla (resp.prefixovala nějakým nesmyslem, jaký nikdy neuhodne)
8) to if(!defined("BASE_PATH")) exit("No direct script access allowed"); tam taky nemá co dělat, aplikace má být mimo Document Root
9) komentáře nejsou často správně použity, nejhorší je snad: // metóda ktorá vypíše dáta - ta metoda nic nevypisuje, jen vrací
Hmm, jedine co ma zaujalo je, preco triedy model aj controller rozsiruju Framework. Nejak mi to unika :) Ale inac je to pekne ako ludom priblizit MVC. :)
Clanok je super, este by som urcite prioritne obsah view suboru, tlacil do layoutu, alebo aspon view vypisoval uplne po zbehnuti controllera.
ob_start();
include_once $view;
$content=ob_get_clean();
Daju sa tak lepsie zachytit pripadne chyby vo view a hlavne aj ovplyvnit layout (nastavenie title, pridanie .css .js a pod.)
Ale clanok urcite trochu pomoze zorientovat sa v zlozitejsich MVC frameworkoch.
Co sa tyka shorttags, ja ich pouzivam rovnako ako andrej a verim, ze keby svoj framework zacal profesionalne pouzivat, alebo ho dokoncil a otvoril svetu tak popri pisani komentarov by si aj tie tagy opravil. Dovtedy usetreny cas moze venovat do dalsieho programovania a najma pisania clankov.
@Matus sorry man aj tak nesuhlasim s tebou :-D ale aby som sa tu len nestazoval tak clanok je fajn, skoda, ze som take nevidel pred par rokmi ked som zacinal kodit
tu je tiez fajny tutorial ako na vlastny FW http://net.tutsplus.com/tutorials/php/creating-a-php5-framework-part-1/
@Lukas Zend Framework ich pouziva vo velkom, pokial viem :) A nie, fakt nie su, ani nebudu deprecated, iba ich nepodporuju niektore pochybne hostingy (to moze byt jediny dovod preco ich nepouzit). Podla mna setria cas, usetris 7 znakov pri kazdom vypise.. a vypisov byva mrte.
Novinky
10 hod.
Kim Dotcom: Vynašiel som dvojfaktorovú autentifikáciu, Google a Facebook porušujú môj patent
Kim Dotcom, zakladateľ Spojenými štátmi rozloženej služby pre zdieľanie súborov Megaupload, dnes prekvapil vyhlásením, že vynašiel dvojfaktorovú autentifikáciu a mnohé spoločnosti vrátane Google, Facebooku a Twitteru porušujú jeho patent.
10 hod.
Internet Explorer 10 chráni pred vírusmi viac ako konkurencia
Používatelia najnovšieho Internet Explorera sú pred škodlivými súbormi chránení viac ako priaznivci konkurenčných internetových prehliadačov...
10 hod.
Xbox One: technologický rozbor nového hardwaru
Microsoft po Sony představil novou generaci vlastní konzole Xbox One, která po osmi letech přináší konečně moderní hardware. Chcete vědět podrobné detaily?
11 hod.
Samsung predal 10 miliónov S4, za menej ako mesiac
Spoločnosť Samsung dosiahla u svojho nového najvyššieho modelu smartfónu Galaxy S4 hranicu desať miliónov predaných kusov.
1 dňom
Microsoft paroduje Google Chrome. Zarába na vás, odkazuje (video)
Konfrontácia medzi spoločnosťami Microsoft a Google pokračuje. Okrem ultimáta týkajúceho sa aplikácie YouTube sa najnovšie na internete objavilo video, ktorého hlavnou obeťou sa stal čoraz populárnejší internetový prehliadača Google Chrome.
Staršie novinky »TOP dlhšie
- 01 3 praktické CSS postupy, o ktorých ste možno nevedeli... (4795x)
- 02 3 jednoduché kroky ako spraviť responzibilný dizajn webu (4088x)
- 03 Fenomén doby: Dosť bolo transparentných ikoniek! (3906x)
- 04 PayPerPost.sk - zarábajte s webom na článkoch (3661x)
- 05 Prečo sa chcem naučiť programovať web stránky? (3573x)
- Aj ty môžeš byť najčítanejší. Napíš článok »
TOP tento mesiac
- 01 Mobil Rulezz: Najlepšia brandovaná aplikácia z agentúry SCR (986x)
- 02 Poctivým zľavovým serverom sa naďalej darí (963x)
- 03 HTML WebSocket - chat v node.js za 5 minút (799x)
- 04 Nová affiliate reklamná sieť z dielne VISIBILITY (732x)
- 05 Magazín Womanman už aj v Apple aplikácii (141x)
- Aj ty môžeš byť najčítanejší. Napíš článok »
Nové články:
- 19.HTML WebSocket - chat v node.js za 5 minút
máj - 14.Poctivým zľavovým serverom sa naďalej darí
máj - 9.Nová affiliate reklamná sieť z dielne VISIBILITY
máj - 26.Mobil Rulezz: Najlepšia brandovaná aplikácia z agentúry SCR
apr - 26.Magazín Womanman už aj v Apple aplikácii
apr - Viac »
- Aj ty môžeš byť najčítanejší. Napíš článok »
Pekné veci
Pekné veci
Pekné veci
Pekné veci
Posledné komentáre
- @- ani ty mna nechapes. od zaciatku sa to nejak povazovalo za komunitny web. pomahali sm...
- dik obom za info. presne o to mi ide, snazim sa zistit ci na blogu mozem pouzit foto ...
- no podla tvojej otazky... podla mna fotkan ako mercne ucely je pouzitelna aj pre a) aj p...
- Diky za článok :). +1 PS: ak niekto má nejaký dobrý článok o (WS) tomto nech dá vedieť ...
- hi ja pod fotkou na komercne ucely rozumiem to ze sa dane fotky idu nahodit na web kt...
Kritika
Vieš ako robiť veci lepšie? Pomôž našim odvážnejším členom a skritizuj im projekty!
Reklama
Slovenská IT komunita
Seriály zo Zajtra.sk
· Ako písať blog
· Ako sa stať PHP ninja s Yii Frameworkom
· Aplikácie pre Facebook
· CSS triky
· iOS vývojára príhody a skúsenosti
· Modelovanie webového sídla
· Nauč sa CodeIgniter [HD]
· Nauč sa jQuery [HD]
· Nette PHP framework
· OOP v Javascripte
· Slovenskí iOS developeri
· Yablkov TurboTip [HD]



















odporúčam radšej tento článok http://symfony.com/doc/current/book/from_flat_php_to_symfony2.html je tam pekne na príklade ukázané aký má vôbec MVC význam (angličtina potrebná)