Model-View-Controller arhitektūras principi (2. daļa)
Ar šo rakstu centīšos parādīt to, kā iepriekš apskatīto kodu būtu iespējams sadalīt pēc Model View Controller arhitektūras principiem. Veidi kā to izdarīt ir dažādi un katra ietvara (framework) MVC realizācija var atšķirties. Šis konkrētais piemērs būs uz manis izstrādātā PHP ietvara balstīts.
/public_html
Publiski pieejamais kods (css, bildes, javascript faili u.tml.)
/private
Php faili, kuros atrodas kods, kas veic pašas aplikācijas pieprasījumu apstrādi un izpildi, datu atlasīšanu no datu bāzes u.tml.
/public_html/index.php
Lielākoties PHP MVC ietvaros tiek lietots Frontend pattern arhitektūra, t.i. kad visi pieprasījumi tiek apstrādāti centralizēti. Tā arī šeit ir realizēts, tas, ka katrs pieprasījums izsauc index.php failu, no kura tālāk jau tiek izsaukta attiecīgās ietvara klases un metodes, kas veic pieprasījuma apstrādi un atbilstošās Controller klases un metodes atrašanu.
$c = new Framework_Bootstrap(); $c->route();
Bez augstāk esošā koda, vēl arī index.php failā tiek definēti ceļi uz aplikācijas komponentēm.
/public_html/.htaccess
Lai varētu nodrošināt to, ka katrs pieprasījums tiek veikts caur index.php failu, .htaccess failā ir jāieraksta sekojošais:
RewriteEngine on RewriteRule !\.(js|ico|gif|jpg|png|css|swn|html|xml|txt|swf)$ index.php
/private/library
Atrodas ietvara klašu faili, kā arī 3rd party klašu bibliotēkas, piemēram, bilžu apstrādes klase, PDF ģenerēšanas klašu bibliotēka u.c.
/private/config/db.php
Datu bāzes konfigurācijas fails.
<?php
define('DB_HOST', 'localhost');
define('DB_USER', 'user');
define('DB_PSW', 'psw');
define('DB_NAME', 'databasename');
?>
/private/app/models
Atrodas klases, kas veic darbības ar datu bāzi (Model slānis). Katrai datu bāzes tabulai parasti tiek izveidota viena atsevišķa Model klase, piemēram, šinī gadījumā tas ir Product.php.
<?php
class Product extends Framework_Db
{
private $_table = 'product';
private $_pk = 'productId';
function getAll(){
$query = "SELECT * FROM $this->_table";
return $this->selectAll($query);
}
function insert($productName){
$data = array(
'productName' => $productName
);
return parent::insert($this->_table, $data);
}
}
?>
Kā redzams piemērā iepriekšējo datu bāzes vaicājumu
SELECT * FROM product
esam pārvietojuši atsevišķā Model klases metodē, kas pēc tam dos iespēju to izsaukt pēc vajadzības, nepārrakstot vairākkārtīgi pašu datu bāzes vaicājumu. Tāpat arī šeit tiek likti visi pārējie datu bāzes vaicājumi, kas attiecas uz datu bāzes tabulu product, piemēram, metode insert($productName). Klase Product tiek paplašināta ar ietvara klasi Framework_Db, kas nodrošinās sql vaicājumu sagatavošanu un datu atgriešanu no datu bāzes.
/private/app/backend
Satura pārvaldības sistēma (CMS), kas ir atsevišķi atdalīta no lapas apmeklētājiem publiski pieejamās daļas, piemēram, atrodas subdomēnā cms.mansdomens.lv. Šāda pieeja ļauj izstrādāt no lapas apmeklētājiem publiski pieejamās lapas satura, atdalītu sistēmu, bet tomēr atļaujot kopīgi izmantot Model klases, piemēram, datu ievietošana tabulā product, var būt nepieciešama, gan lapas lietotājiem, gan lapas administratoram, kas rediģē aplikācijas datu bāzi speciāli izveidotā cms sistēmā.
/private/app/frontend
Publiski pieejamā sadaļa. Tā kā zem frontend un backend esošā failu struktūra ir līdzīga, tad tālāk apskatīsim tikai frontend sadaļu.
/private/app/frontend/layouts
Atrodas view slāņa layout faili, kuri kalpo kā pamata html šablons, kurā noteiktās vietās tiek pievienots mainīgais lapas saturs.
/private/app/frontend/layouts/index.phtml
</pre> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Paraugs</title> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> </head> <body> <?=$this->layout['center']?> </body> </html>
<?=$this->layout['center']?> vietā tiek ievietots konkrētā piepasījuma view fails, kuru apskatīsim vēlāk.
/private/app/frontend/modules
Tā kā tiek veidota modulāra aplikācija, tad tiek veidoti moduļi, kas katrs sevī var saturēt vairākas Controller un View komponentes.
/private/app/frontend/modules/product/controllers
Product moduļa Controller slānis.
/private/app/frontend/modules/product/controllers/PrintController.php
Product moduļa Controller klase.
<?php
class Product_PrintController extends Framework_Controller {
function indexAction(){
require_once PATH_TO_MODELS.'Product.php';
$o_product = new Product();
$this->view['product'] = $o_product->getAll();
$this->layout['center'] = $this->render('index');
$this->layout();
}
}
?>
Web aplikācijas adrese, lai izsauktu product moduļa PrintController klases indexAction() metodi, būs mansdomens.lv/product/print vai mansdomens.lv/product/print/index.
Kā redzams PrintController klases indexAction() metodē, tad tiek izsaukta Model slāņa Product klases metode getAll(), kas atgriež masīvā visu produktu sarakstu un šis masīvs tiek noglabāts mainīgajā $this->view['product'], kura vērtībām pēc tam varēs piekļūt view slāņa failos.
Metode $this->render(‘index’); ģenerē attiecīgā Controller, attiecīgās Action metodes view failu (/private/app/frontend/modules/product/views/print/index.phtml).
$this->layout(); izsauc /private/app/frontend/layouts/index.phtml failu, kurā tiek ierakstīts $this->layout['center'] esošā view faila vērtība, līdz ar to iegūstot gatavu html lapu, kas ir redzama lietotājam.
/private/app/frontend/modules/product/views/print/index.phtml
Product moduļa View slāņa fails. Šeit tiek likts html izejas kods, kas tiek iekļauts layouts html failos.
<table>
<tr>
<th>produkts</th>
<?
foreach($this->view['product'] as $row) {?>
<tr><td><?=$row['productName']?></td></tr>
<? }?>
</tr>
</table>
Šīs ir tikai viens no veidiem, kā varētu realizēt Model View Controller arhitektūru. Lai iegūtu labāku priekšstatu par šo tik izplatīto arhitektūru, iesaku pašiem praktiski pamēģināt vairākus piemērus, lai izprasto šo tēmu labāk:




