Postup Úvodem Můj úkol při tomto projektu byl vytvořit model pro data, dle návrhového vzoru MVC. Jelikož v poslední době pracuji spíše s návrhovým vzorem HMVC (http://en.wikipedia.org/wiki/hmvc) ve frameworku CodeIgniter (http://ellislab.com/codeigniter + extenze pro modulárnost podle vzoru HMVC (https://bitbucket.org/wiredesignz/codeigniter modular extensions hmvc)), rozhodl jsem se rošířit si úkol o vytvoření základního frameworku, využívající právě principy HMVC. Hlavní myšlenka frameworku Celá aplikace je tvořena čtyřmi základními složkami v adresářové struktuře: /application uchovávající konfigurační soubory a samotné moduly /system takzvané jádro frameworku obsahující všechny základní třídy, nutné pro jeho chod /assets externí prvky celé aplikace (kaskádové styly, javascriptové soubory) /uploads externí data pro moduly, nenalézající se v databázi (obrázky v galerii, nahrané soubory, atd.) application Tato složka je tvořena dvěma podsložkami, a to:./config Konfigurační soubory./modules Samotné moduly tvořící aplikaci system Tato složka je tvořena dvěma podsložkami, a to:./core Základní třídy frameworku nutné pro jeho správný chod./exceptions Vyjímky pro základní třídy, abychom dodržovali zásady OOP assets Tato složka, sloužící pro uchovávaní externích souborů pro aplikaci obsahuje dvě vnořené složky, a to:./css Kaskádové styly, může obsahovat další složky, dle uvážení člověka, který bude framework implementovat./js Javascriptové soubory, platí pro ně stejná pravidla jako pro./css uploads Složka sloužící pro externí soubory, které nejsou nutné pro správný chod aplikace, ale většinou obsahují externí zdroje pro moduly, proto ve výchozí instalaci frameworku obsahuje jendu složku, a to:./modules Pokud je externí zdroj určen pro nějaký modul v./application/modules/ je zde vytvořena složka se jménem modulu, a tyto externí zdroje jsou ukládany zde (např. ve finální aplikaci je modul gallery, sloužící pro nahrávání fotografií, proto se v
./uploads/modules/ vytvoří složka gallery a do ní se fotografie nahrávají) Flow frameworku Jako většina (H)MVC frameworků i já jsem zvolil nejjednoduší metodu celé aplikační logiky frameworku, kterou nejlépe nastiňuje následující obrázek: Celý framework tedy funguje v několika málo krocích, které nakonec vedou k předání všech nutných dat, jejich případné zpracování, předání View a jeho vyrenderování: 1. index.php základní soubor, na který směřují všechny odkazy a je srdcem celého frameworku je soubor index.php jsou v něm definovány všechny nutné základní konstanty (cesta k adresářům application a system), nastartovány Sessiony, a definována kořenová složka, pro případ, že by aplikace něběžela v rootu webu, ale například v podsložce. Dále je zde includován soubor FW.php který je mozkem frameworku, takzvaný bootstrap 2. FW.php bootstrap soubor, jehož úkolem je nastavit prostředí pro běh frameworku, je zde definována funkce zpracovavájící nezachycené vyjímky (všimněte si použití novinky PHP 5.4, a to anonymní funkce) includování základního souboru s chybami pro vyjímky (system/exceptions/error.php), základní třídy pro Controller (system/core/controller.php) a model (system/core/model.php), dále definování důležité funkce, umožňující nám kdekoliv
framework (procedurální funkce, helpery (nebyla nutnost implementovat), atd.) Přistupovat k celé instanci frameworku včetně načtených tříd, modulů, atd. Dále jsou načteny základní třídy nutné pro chod (Router,Loader, Input, Upload, Session), poté se plynule přechází do nejdůležitější části celého systému, a to tzv Routingu 3. Routing je proces rozdělení částí URL na odpovídající segmenty, v tomto případě je schéma následující: URL adresy jsou systémem generovány ve formátu index.php?q=module/controller_modulu./metoda_modulu/parametr_klic/parametr_hodno ta/parametr2_klic/parametr2_hodnota/ routerem je toto rozděleno, načteno do privátních hodnot uvniř třídy Router, a dá se k nim přistupovat přes get_ metody. Podle těchto získaných hodnot je pak modul nalezen, načten do instance frameworku a spuštěn pomocí call_user_func_array Základní třídy HMVC Jakmile bylo zajištěno správné routování, další úkol byl napsání základních tříd pro správné fungování MVC modelu, začneme s tou nejdůležitější, a to Controller. Controller Tato třída zajišťuje dostupnost nahraných modulů a knihoven každému controlleru v modulu, proto z ní každý controller v modulu dědí. Toto zajištění se děje skrze funkci is_loaded() která ve statickém poli drží seznam věcí, které jsme v této instanci frameworku načetli. Toto pole je při dalším requestu procházeno, a třídy v něm jsou načítány aby byly dostupné. Samozřejmě se znovu neincludují soubory, pouze se vrátí instance objektu který chceme načís, tudíž includování souborů probíhá pouze jednou, při prvním načtení frameworku. Model Z této třídí dědí všechny modely v modulu, zajišťuje přístup k načteným objektům frameworku a taktéž zajišťuje přístup k databázi skrze třídu MySQL. Jelikož Třída Model nedědí ze třídy Controller je zajištění přístupu k načteným objektům zajištěno skrze magickou metodu get() Dále bylo důležiti inicializovat v construct() databázi, která je poté přístupná každému modelu skrz veřejnou proměnnou $db
Loader Tato třída slouží pro nahrávání objektů do frameworku, (moduly, views, modely, knihovny) Veškeré detaily použití jsou popsány v kódu pomocí standardního DocBlocku Další třídy V jádru frameworku je zakomponováno několik dalších tříd usnadňujících určité aspekty tvorby aplikace. Např. : Input Třída pro $_GET a $_POST globální proměnné, sanitizuje data v nich a poskytuje jednodtné přístupové rozhraní Session Třída pro práci se Session daty Upload Třída usnadňující upload souborů (zvládá upload více naráz, čistí nazvy souborů od diakritiky atd.) Práce s frameworkem Jakmile byly hotové základní třídy, a framework odladěn, byl čas pustit se do tvorby modulů, což měl na starosti Ondřej Matula. Samozřejmě je toto systém, se kterým nemohl být obeznámen, jelikož byl mojí vyroby, proto jsem mu s tvorbou modulů asistoval, a proto zde na závěr popíšu, jak se takový modul do mého frameworku tvoři 1. Vytvoření složek každý modul musí obsahovat tři složky, a to: a. controllers Controllery, jedná se o třídy, které dědí ze základní třídy Controller popsané výše b. models Modely s přístupem k databázi, jedná se o třídy dědící ze základní třídy Model popsané výše c. views Samotné views zobrazující data 2. Napsání controlleru Vytvoření třídy dědící z třídy Controller (class Modul extends Controller), případné nahrání modelu ($this >loader >model( module_model, module_name )) který je díky architektuře frameworku poté dostupný v globální instanci $this, případné nahrání dalších potřebných modulu ($this >loader >module( module_name )), taktéž dostupný v $this Napsání samotné logiky controlleru, views se nahrávají přes $this >loader >view( view_name, module ) 3. Napsání modelu Vytvoření třídy dědící ze základní třídy Model, napsání metod por získání dat 4. Vytvoření views Vytvoření HTML šablon využívajících data získaná z modelu 5. Vyrenderování do šablony V modulu main se nachází controller Main obsahující metody pro zadání titulku, nastavení obsahu, a vyrenderování to šablony, která se nachází ve složce views modulu Main (modules/main/views/tamplate.php) 6. Případné vrácení dat Pokud nechceme přímo renderovat, ale využít data z controlleru například v jiném modulu 7. Přístup k modulu V podstatě existují dvě možnosti
a. Příme nahrání skrz URL (index.php?q=module/module_controller/module_method/parameters) b. Nebo nahrání v jiném modulu a využití dat ($this >loader >module( module ))