You are on page 1of 18

MVC l mt m hnh chun.

Mt mu thit k m gip to nn mt cu trc m cho php cho cc khun kh ng dng nhn rng mt cch nhanh chng. Bn c th ngh y nh mt khung sn, mt khun kh m trn cc ng dng ca bn s c xy dng.

Trch dn:Ti sao ta phi vit theo m hnh MVC? M hnh MVC c nhng li ch g? V hu ht cc CMS hin i nh: joomla, e-commence, drupal, e-shop, open cart; v c cc framework ni ting nh: CI (CodeIgniter), CakePHP, Zend, Yii u phi tun theo m hnh MVC ny? khng mt thi gian, ti ch hng dn cc bn t chc 1 project MVC, cc bn c th tham kho video v m sau hiu r thm v m hnh ny:http://cione.com.vn/Videos/248/huong-dan...-trong-php V cc bn s hay t cu hi phn vn l ti nn hc framework g? Joomla, Drupal, CI, CakePHP hay Zend,...? Theo kinh nghim ca ti l bn m hy bt u vi MVC chun m ti s hng dn sau y hiu c ch lm vic sau c th chn 1 trong cc framework (FW) trn hc, v cc CMS hay FW ny u tun theo m hnh MVC th ch khc nhau v cc phng thc h tr thi, ch v bn cht v cu trc cc phn (MVC) u ging nhau c! Theo ti th nn chn t FW d n kh hc c ci hay ca mi FW, hy bt u vi CI hoc CakePHP, mnh nh gi cao v CI (chy nhanh, d pht trin v t bit a s LTV VN hay si FW ny)

Gii thiu: y l bi hng dn cch xy dng 1 MVC framework n gin t mi


bt u n kt thc. Theo nh hnh v trn cc bn s thy cc lp nh: Controller, Model, View c tch ra r rt: Client request n Controller, Controller s quyt nh c nn s dng Model hay trc tip qua View

Trong lot hng dn sau, ti s lit k 1 s im quan trng, nh vic u tin m framework cn lm l to im bt u (vd: index.php), l ni m cho php tt c cc controller c th thng qua v hot ng. lm iu ny ta s dng mod_rewrite, 1 mt gip ta c th to ra im bt u cc controller hot ng, 1 mt gip ta to ra 1 ng dn thn thin (SEO URL) gip cc

b my tm kim index nhanh hn. VD: File .htaccess s vit li ng dn cho ta c dng: http://www.example.com/news/show Nu nh khng dng th dng dn ra c dng: http://www.example.com/index.php?rt=news/show y l file .htaccess ca ng dng: M PHP: (SELECT ALL)
RewriteEngine on # Cho nay la duong dan chinh cua thu muc lam viec (http://localhost/) => RewriteBase / # Neu thuc muc la http://localhost/shop/ => RewriteBase /shop/ RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?rt=$1 [L,QSA]

Cu trc ca ng dng MVC: M PHP: (SELECT ALL)


application controller includes model views .htaccess index.php

Phn Index: /index.php

Nh cp trc , tp tin index.php l im duy nht chng ta truy cp ng dng. Nh vy, n cung cp khng gian l tng khai bo cc bin v cu hnh trang web rng. Trong tp tin ny ti cng s gi mt hay mt vi tp tin tr gip khi to bin, cu hnh,.... Tp tin ny s c gi l init.php v n s c t trong includes: /index.php: M PHP: (SELECT ALL)
<?php /*** error reporting on ***/ error_reporting(E_ALL);

/*** define the site path ***/ $site_path = realpath(dirname(__FILE__)); define ('__SITE_PATH', $site_path); /*** include the config.php file ***/ include 'config.php'; /*** include the init.php file ***/ include 'includes/init.php'; ?>

index.php thit lp cc bo co li (error_reporting), include tp tin init.php, v define hng s ng dn tnh ca website (__SITE_PATH). V ti y .htaccess s bt u xy dng registry, cc object registry ny c xy dng thng qua nhng bin ton cc m ta xy dng, to ra i tng ny ta to ra init.php: D nhin l trc khi to ra tp tin ny, chng ta cn phi nh ngha cc lp cn thit cho h thng nh: controller, registry, router, template. Cc lp ny s t ng include vo chng trnh (bt buc h thng hot ng). /includes/init.php M PHP: (SELECT ALL)
<?php /*** include the controller class ***/ include __SITE_PATH . '/application/' . 'controller_base.class.php'; /*** include the view class ***/ include __SITE_PATH . '/application/' . 'view_base.class.php'; /*** include the model class ***/ include __SITE_PATH . '/application/' . 'model_base.class.php'; /*** include the registry class ***/ include __SITE_PATH . '/application/' . 'registry.class.php'; /*** include the router class ***/ include __SITE_PATH . '/application/' . 'router.class.php'; /*** a new registry object ***/ $registry = new registry;

?>

Phn Registry:

Registry l 1 i tng (registry object) cho php lu __set() v truy xut __get() cc bin m ta khng cn phi s dng bin ton cc (global variable). M PHP: (SELECT ALL)
<?php Class Registry { /* * @the vars array * @access private */ private $vars = array();

/** * * @set undefined vars * * @param string $index * * @param mixed $value * * @return void * */ public function __set($index, $value) { $this->vars[$index] = $value; } /** * * @get variables * * @param mixed $index * * @return mixed *

*/ public function __get($index) { return $this->vars[$index]; } } ?> [php] Chng ta thy c 2 phng thc t ng: __set() v __get() to ra cc bin s dng xuyn sut t rong chng trnh nh global variable. Cch s dng: [php] $registry->newval = 'This is value of variable name newval'; echo $registry->newval;

Phn Router:

y l lp gip m hnh MVC chn ng controller lm vic: V d ta c 1 router s dng controller "new": http://www.example.com/index.php?rt=news Nu ta s dng mod_rewrite th url c dng: http://www.example.com/news /application/router.class.php: M PHP: (SELECT ALL)
<?php class router { /* * @the registry */ private $registry; /* * @the controller path */ private $path; private $args = array(); public $file;

public $controller; public $action; function __construct($registry) { $this->registry = $registry; }

Phng thc khi to class router s gip ta to mi 1 object router thng qua object $registry m ta to sn trong init.php. Thm on m sau thc hin to mi 1 router trong index.php: M PHP: (SELECT ALL)
*** load the router ***/ $registry->router = new router($registry);

chn c th mc controller lm vic ta vit thm phng thc setPath trong router.class.php: M PHP: (SELECT ALL)
/** * * @set controller directory path * * @param string $path * * @return void * */ function setPath($path) { /*** check if path i sa directory ***/ if (is_dir($path) == false) { throw new Exception ('Invalid controller path: `' . $path . '`'); } /*** set the path ***/ $this->path = $path; }

...V by gi ta truyn th mc controller lm vic cho lp router trong index.php: M PHP: (SELECT ALL)

/*** set the path to the controllers directory ***/ $router->setPath (__SITE_PATH . 'controller');

Sau khi router kim tra tnh hp l ca controller truyn vo qua phng thc setPath(), ta tip tc load controller: M PHP: (SELECT ALL)
/** * * @load the controller * * @access public * * @return void * */ public function loader() { /*** check the route ***/ $this->getController(); /*** if the file is not there diaf ***/ if (is_readable($this->file) == false) { $this->file = $this->path.'/error404.php'; $this->controller = 'error404'; } /*** include the controller ***/ include $this->file; /*** a new controller class instance ***/ $class = $this->controller . 'Controller'; $controller = new $class($this->registry); /*** check if the action is callable ***/ if (is_callable(array($controller, $this->action)) == false) { $action = 'index'; } else { $action = $this->action;

} /*** run the action ***/ if(!empty($this->args)) $controller->$action($this->args); else $controller->$action(); }

Phng thc loader() s triu gi phng thc getController() vi ngha getController() s thng qua query string: $_GET['rt'] m ta truyn (http://example/index.php?rt=news/view/3) xc nh controller m ta thc hin. Trong trng hp vi controller "news" vi url (http://example/index.php?rt=news) th controller s s dng lp news controller vi phng thc index(). Trng hp vi controller "news/view" vi url (http://example/index.php?rt=news/view/3) th controller s s dng lp news controller vi phng thc view($arg) vi $arg[1] = 3. Chng ta s hiu r v router hn phn vit 1 ng dng blog nho nh! M PHP: (SELECT ALL)
/** * * @get the controller * * @access private * * @return void * */ private function getController() { /*** get the route from the url ***/ $route = (empty($_GET['rt'])) ? '' : $_GET['rt']; if (empty($route)) { $route = 'index'; } else { /*** get the parts of the route ***/ $parts = explode('/', $route); $this->controller = $parts[0]; if(isset( $parts[1])) {

$this->action = $parts[1]; } if(isset( $parts[2])) { $count_args = count($parts); $k = 1; $args = array(); for($i = 2; $i < $count_args; $i++) $args[$k++] = $parts[$i]; $this->args = $args; } } if (empty($this->controller)) { $this->controller = 'index'; } /*** Get action ***/ if (empty($this->action)) { $this->action = 'index'; } /*** set the file path ***/ $this->file = $this->path .'/'. $this->controller . 'Controller.php'; }

Phn Controller:

Controller (C trong MVC) l 1 lp tru tng nh ngha ra tt c cc controller ca ng dng, n bao gm: object $registry h tr truyn d liu, object $model ly d liu t Model (M), object $view truyn data v xut View (V) phng thc mc nh index() cho controller khng c action (task) nh v d truyn vo router vi 2 tham s "news v news/view/id" v d phn Router M PHP: (SELECT ALL)
<?php Abstract Class baseController { /* * @registry object */ protected $registry;

protected $model; protected $view; function __construct($registry) { $this->registry = $registry; $this->model = &baseModel::getInstance(); $this->view } = &baseView::getInstance();

/** * @all controllers must contain an index method */ abstract function index(); } ?>

Phn Model: Model (M trong MVC) Thnh phn x l cc d liu t textfile, database, objects,.... baseModel s c triu gi t Controller khi cn n, baseModel c nhim v thao tc vi Database M PHP: (SELECT ALL)
<?php class baseModel { private static $instance; function __construct() { } public static function getInstance() { if (!self::$instance) { self::$instance = new baseModel(); } return self::$instance; } public function get($name){ $file = __SITE_PATH.'/model/'.str_replace("model","",strtolower($name))."Model.php"; if(file_exists($file)) { include ($file); $class = str_replace("model","",strtolower($name))."Model"; return new $class;

} return NULL; } function __destruct() { } }

Phn View:

View (V trong MVC) l phn nh dng d liu, gi v nhn d liu t form, hin th html & css,... View ngoi phng thc set dng gi data t controller sang, view cn phng thc show() gip controller chn la tn view cn s dng: /application/view_base.class.php M PHP: (SELECT ALL)
<?php Class baseView {

/* * @Variables array * @access public */ public $data = array(); private static $instance; /** * * @constructor * * @access public * * @return void * */ function __construct() { } public static function getInstance() { if (!self::$instance)

{ self::$instance = new baseView(); } return self::$instance; } /** * * @set undefined vars * * @param string $index * * @param mixed $value * * @return void * */ public function __set($index, $value) { $this->vars[$index] = $value; }

function show($name) { $path = __SITE_PATH . '/views' . '/' . $name . '.php'; if (file_exists($path) == false) { throw new Exception('Template not found in '. $path); return false; } // Load variables foreach ($this->data as $key => $value) { $$key = $value; } include ($path); }

?>

Vit ng dng:

Vit 1 ng dng blog c chc nng nh sau: 1/ Nu ngi dng truy cp http://example.com/ th s xut ra mn hnh dng ch "Welcome to My Blog!" Mc nh nu ngi dng khng g Controller, th h thng s chn ly indexController lm vic (nu khng c th s dng /controller/error404.php) Ta to: /controller/error404.php khi khng tm thy Controller th s hin th ra ni dung: M PHP: (SELECT ALL)
<?php Class error404Controller Extends baseController { public function index() { $this->view->data['blog_heading'] = 'This is the 404'; $this->view->show('error404'); } } ?>

Vi error404Controller c s dng View "error404". Ta to /views/error404.php c ni dung sau: M PHP: (SELECT ALL)
<h1><?php echo $blog_heading; ?></h1> <p>This is a custom 404 error page.</p> <p>You can put whatever content you like here such as search for your site</p>

Tip theo ta to Controller Index: Ta to: /controller/indexController.php vi phng thc index() l phng thc mc nh: M PHP: (SELECT ALL)
<?php Class indexController Extends baseController { public function index() { /*** set a template variable ***/ $this->view->data['welcome'] = 'Welcome to My Blog!'; /*** load the index template ***/ $this->view->show('index'); }

} ?>

Vi indexController c s dng View "index". Ta to /views/index.php c ni dung sau: M PHP: (SELECT ALL)
<h1><?php echo $welcome; ?></h1>

Nh vy l xong, by gi ta test kt qu: G http://example.com/ th s xut ra mn hnh dng ch "Welcome to My Blog!" G http://example.com/noway th s xut ra thng bo li khng tm thy trang. 2/ Nu ngi dng truy cp http://example.com/blog th s xut ra mn hnh tt c cc bi Blog u tin ta to 1 database n gin c tn "framework" v 1 table "blog" gm 3 trng id, name v content. M PHP: (SELECT ALL)
CREATE TABLE IF NOT EXISTS `blog` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `content` varchar(500) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB --- Dumping data for table `blog` -INSERT INTO `blog` (`id`, `name`, `content`) VALUES (1, 'MVC Introduction', 'This is content of MVC Introduction'), (2, 'PHP framework', 'This is a content of PHP framework'); DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

Tip theo ta cu hnh kt ni trong: /config.php M PHP: (SELECT ALL)


<?php define('DB_NAME', 'framework'); // Database name define('DB_USER', 'root'); // User database define('DB_PASSWORD', 'vertrigo'); // Password database define('DB_HOST', 'localhost'); // IP host ?>

Tng t nh index Controller ta to ra blog Controller vi action index() cho chc nng

ny: /controller/blogController.php M PHP: (SELECT ALL)


<?php Class blogController Extends baseController { public function index() { $this->view->data['blogs'] = $this->model->get('blogModel')->get_blogs(); $this->view->data['blog_heading'] = 'This is the blog Index'; $this->view->show('blog_index'); } } ?>

Vi blogController c s dng model "blogModel" vi phng thc get_blogs(). Ta to /model/blogModel.php c cha phng thc get_blogs() ly tt c cc blog trong CSDL: M PHP: (SELECT ALL)
<?php Class blogModel Extends baseModel { public function get_blogs() { global $db; $blog = $db->query('SELECT id, name, content FROM blog'); return $db->fetch_object(); } } ?>

Vi blogController c s dng view "blog_index". Ta to /views/blog_index.php c ni dung sau: M PHP: (SELECT ALL)
<h1><?php echo $blog_heading; ?></h1> <ul> <?php foreach($blogs as $blog) : ?> <li>Blog id <?php echo $blog->id; ?>: <a href="blog/view/<?php echo $blog->id; ?>"><?php echo $blog->name; ?></a></li> <?php endforeach; ?> </ul>

Nh vy l xong, chng ta test kt qu: G http://example.com/blog th s xut ra mn hnh tt c cc bi Blog: M PHP: (SELECT ALL)
This is the blog Index Blog id 1: MVC Introduction Blog id 2: PHP framework

3/ Nu ngi dng truy cp http://example.com/blog/view/id th s xut ra mn hnh chi tit ca bi blog c id l "id" Tng t nh blog Controller ta b sung blogController vi action view() cho chc nng ny: /controller/blogController.php M PHP: (SELECT ALL)
<?php Class blogController Extends baseController { public function index() { $this->view->data['blogs'] = $this->model->get('blogModel')->get_blogs(); $this->view->data['blog_heading'] = 'This is the blog Index'; $this->view->show('blog_index'); } public function view($args){ $id_blog = $args[1]; $blog_detail = $this->model->get('blogModel')->get_blog_detail($id_blog); $this->view->data['blog_heading'] = $blog_detail->name; $this->view->data['blog_content'] = $blog_detail->content; $this->view->show('blog_view'); } } ?>

Vi action view() c s dng model "blogModel" vi phng thc get_blog_detail(). Ta b sung /model/blogModel.php phng thc get_blog_detail($id) cho php ly thng tin blog c id l $id: M PHP: (SELECT ALL)

<?php Class blogModel Extends baseModel { public function get_blogs() { global $db; $blog = $db->query('SELECT id, name, content FROM blog'); return $db->fetch_object(); } public function get_blog_detail($id) { global $db; $blog = $db->query('SELECT id, name, content FROM blog where id = '.$db->sqlQuote($id)); return $db->fetch_object($first_row = true); } } ?>

Vi blogController c s dng view "blog_view". Ta to /views/blog_view.php c ni dung sau: M PHP: (SELECT ALL)
<h1><?php echo $blog_heading; ?></h1> <p><?php echo $blog_content; ?></p>

Nh vy l xong, chng ta test kt qu: G http://example.com/blog/view/1 th s xut ra mn hnh chi tit ca bi blog c id l 1 M PHP: (SELECT ALL)
MVC Introduction This is content of MVC Introduction

Kt thc: Qua bi tutorial kh l di, mnh c gng xy dng rt chi tit m hnh MVC
ny, mong cc bn ng gp kin bi vit hon thin hn.

Lu :
- y l m hnh MVC ct li rt n gin, i vi 1 m hnh hon thin cn phi c thm 1 s x l khc nh: helper (ch cc function lm vic), library (cc th vin h tr, c

th m rng), languages (a ngn ng), cache (gip ng dng chy nhanh hn),... v cn nhiu thnh phn khc m bn hy t khm ph nh! - Vi m hnh ny bn c th pht trin thm rt nhiu ty bn, nhng mnh khuyn sau khi chy v hiu r s hot ng m hnh ny, hy bt u ngay vi 1 framework nh CI (CodeIgniter ) bn hiu su hn, ng thi n xy dng tt c cc x l m ti va trnh by, khi bn vit bn s tp trung vo ng dng ca mnh hn so vi xy dng 1 framework rt mt thi gian! - Nu n gin cho bn pht trin thm theo m hnh MVC hy chn ngay CMS vi joomla, vi shop hy chn Open cart: http://www.opencart.com/ xy dng y trang qun tr v cc ngn ng, cng vi cc chc nng tin tc v sn phm, bn ch vit thm 1 s tnh nng nh gi vng, thanh ton ngn lng, qung co,...

You might also like