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
4 mes.
Používatelia Chrome začali prechádzať na nový rýchlejší Firefox, avizujú dáta Mozilly
Nový lepší a rýchlejší prehliadač Firefox 57 Quantum vyúsťuje zrejme do viac používateľov prechádzajúcich respektíve vracajúcich sa na tento prehliadač z iných prehliadačov, na osobných počítačoch aj smartfónoch.
4 mes.
Briti dokončili kúpu SK-NIC-u. Nové .sk domény nechávajú za 8.4 eur
Predaj správcu slovenskej domény .sk, SK-NIC, bol dokončený a novým majiteľom po telekomunikačnej skupine Danubiatel, do ktorej patrí napríklad Swan a 4ka, je britská spoločnosť CentralNic.
4 mes.
Šifrovanie diskov v Linuxe sa výrazne zlepšuje, dostáva ochranu integrity
Technológia šifrovania diskov LUKS podporovaná v Linuxe a využívaná mnohými linuxovými distribúciami dostáva výrazné vylepšenie v podobe vydania novej hlavnej verzie nástroja cryptsetup 2.0.0.
4 mes.
Blýská se Tesle na lepší časy? PepsiCo objednala 100 kamionů Semi
Známá automobilka Tesla má v poslední době problémy s plněním ambiciózních výrobních plánů stanovených vizionářem Muskem a pohybuje se v červených číslech.
4 mes.
DSL rozchodili cez mokrý špagát, dosiahli 3.5 Mbps. Nesimulovali slovenské linky?
Technik menšieho britského telekomunikačného operátora Andrews & Arnold uskutočnil zaujímavý experiment, keď sprevádzkoval pripojenie technológiou ADSL cez namočený špagát.
Staršie novinky »TOP dlhšie
- 01 Git - krátky úvod a prvé príkazy (VIDEO) (1264x)
- 02 TotalCon: konferencia/workshop venový Node.js / Total.js (1247x)
- 03 Notebook roka 2017 – hlasujte teraz (1156x)
- 04 Majte svoj cukor vždy pod kontrolou s glukometrom iHealth ALIGN BG1 (980x)
- 05 Úvod do Raspberry Pi a hry Minecraft (678x)
- Aj ty môžeš byť najčítanejší. Napíš článok »
TOP tento mesiac
- 01 Zábavné programovanie pre deti, 2. časť (374x)
- 02 Prvý ročník open-source konferencie Bratislava OpenCamp je za dverami (226x)
- Aj ty môžeš byť najčítanejší. Napíš článok »
Nové články:
- 21.Vývoj mobilných telefónov za posledných 35 rokov
apr - 11.Prvý ročník open-source konferencie Bratislava OpenCamp je za dverami
apr - 11.PocketBook Touch HD 2 Ruby Red
apr - 2.Zábavné programovanie pre deti, 2. časť
apr - 22.Raspberry Pi a hra Minecraft II.: Staviam - staviaš - staviame
mar - Viac »
- Aj ty môžeš byť najčítanejší. Napíš článok »
Pekné veci
Pekné veci
Pekné veci
Pekné veci
Posledné komentáre
- Inak Minecraft PI sa dá nainštalovať aj priamo do Retropie - inštaluje sa to obvykle ext...
- odporúčam http://www.arcadepunks.com/retro-pi-downloads-page/ Sú tam hotové IMG s tis...
- Naliehavá výzva protestným zhromaždeniam na námestiach! Poznajte, ako je vami manipulova...
- @Sleepy Ďakujem :) .. RetroPie som doteraz neskúšala, ale pozerám, že to vyzerá veľmi za...
- Pekný článok. Ja som sa pustil do RPi pretože som chcel skúsiť RetroPie a musím povedať,...
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
· Jednoduché programy, ktoré vám ušetria čas
· Modelovanie webového sídla
· Nauč sa CodeIgniter [HD]
· Nauč sa jQuery [HD]
· Nette PHP framework
· OOP v Javascripte
· Programujeme v Jave
· Programujeme v Lazaruse
· Programujeme v Pythone
· Robíme Eshop v ASP.NET Web Pages
· Slovenskí iOS developeri
· Webdizajn krok po kroku
· 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á)