You are on page 1of 19

Le modle MVC et le contrleur sous PHP

par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)
Date de publication : 28/06/2007 Dernire mise jour : 12/10/2009

De tous les motifs de conception (Design patterns), le motif MVC est sans doute celui sur lequel il y a le plus dire. Je vais cependant rester simple, le but de cet article est de comprendre MVC, et pourquoi MVC ?

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

I - Introduction..............................................................................................................................................................3 II - Principe du modle MVC.......................................................................................................................................6 III - Le frontController ou contrleur frontal.................................................................................................................9 IV - Motif actionController.......................................................................................................................................... 14 V - Conclusions..........................................................................................................................................................19

-2Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

I - Introduction
Le MVC tout comme l'orientation objet du code, semble tre devenu un standard dans le developpement d'applications web, avec la rputation d'tre une bonne pratique de conception. Cependant, trouver une definition exacte et prcise du MVC semble impossible, notamment au regard de PHP, langage script interprt chaque requte, la diffrence de java avec qui on peut utiliser les threads et o le serveur web est spar du serveur d'application grant les objets, leur tat et leur persistance. De nombreux Frameworks utilisent aujourd'hui MVC, car le but principal de ce motif est de sparer les couches logiques d'une application. Nous allons voir qu'il n'est pas toujours judicieux d'utiliser MVC, ce motif sera plutt rserv aux sites touffus, dans lesquels beaucoup de redondances de code apparaissent en gnral, des sites souvent mis jour, souvent remodels. Dans le cadre d'une petite application web "gentillette" la complexit en terme de code, apporte par MVC, ne sera pas justifie. En revanche pour tout autre projet web, la sparation en plusieurs couches permet diffrentes quipes de travailler chacune sur une couche, indpendamment des autres. Et c'est aussi un gros avantage lorsqu'une couche doit voluer, sans que les autres n'en aient besoin. Voyons dj un petit code :
<?php $connect = mysql_connect('myserver', 'mylogin', 'mypassword'); mysql_select_db('myDB'); if ($_SERVER['REQUEST_METHOD'] == 'POST') { $news_id = $_POST['news_id']; mysql_query("INSERT INTO commentaires SET news_id='$news_id', auteur='".mysql_escape_string($_POST['auteur'])."', texte='".mysql_escape_string($_POST['texte'])."', date=NOW()" ); header("location: ".$_SERVER['SCRIPT_NAME']."?news_id=$news_id"); exit; } else { $news_id = $_GET['news_id']; } ?> <html> <head> <title>Les news</title> </head> <body> <h1>Les news</h1> <div id="news"> <?php $news_req = mysql_query("SELECT * FROM news WHERE id='$news_id'"); $news = mysql_fetch_array($news_req); ?> <h2><?php echo $news['titre'] ?> poste le <?php echo $news['date'] ?></h2> <p><?php echo $news['texte_nouvelle'] ?> </p> <?php $comment_req = mysql_query("SELECT * FROM commentaires WHERE news_id='$news_id'"); $nbre_comment = mysql_num_rows($comment_req); ?> <h3><?php echo $nbre_comment ?> commentaires relatifs cette nouvelle</h3> <?php while ($comment = mysql_fetch_array($comment_req)) {?> <h3><?php echo $comment['auteur'] ?> a crit le <?php echo $comment['date'] ?></h3> <p><?php echo $comment['texte'] ?></p> <?php } ?> <form method="POST" action="<?php echo $_SERVER['SCRIPT_NAME'] ?>" name="ajoutcomment"> <input type="hidden" name="news_id" value="<?php echo $news_id?>"> <input type="text" name="auteur" value="Votre nom"><br /> <textarea name="texte" rows="5" cols="10">Saisissez votre commentaire</textarea><br /> <input type="submit" name="submit" value="Envoyer"> </form> </div> </body> </html>

-3Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

C'est volontairement simple et simplifi, peu scuris, ceci pour demeurer concis et clair, constat : tout le monde connat un code comme celui-ci, et a ne choquera personne. PHP est mlang au sein du HTML, aprs tout c'est son but premier : langage prprocesseur. A la lecture du code, on comprend immdiatement ce quoi il est destin, c'est l'avantage. On appelle a un traitement procdural. L'inconvnient, c'est que les couches sont mlanges. Dans le traitement d'informations sur le web, gnralement on distingue 3 couches : le modle qui gre la manire d'accder aux donnes, la vue qui se charge de prsenter des donnes, et le contrle, c'est l'tape intermdiaire de slection et fusion des donnes. On peut donc factoriser le code pour bien sparer ces 3 couches, voyez plutt : mymodel.php
<?php function dbconnect() { static $connect = null; if ($connect === null) { $connect = mysql_connect('myserver', 'mylogin', 'mypassword'); mysql_select_db('myDB'); } return $connect; } function get_news($id) { $news_req = mysql_query("SELECT * FROM news WHERE id='(int)$id'",dbconnect()); return mysql_fetch_array($news_req); } function get_comment($news_id) { $comment_req = mysql_query("SELECT * FROM commentaires WHERE news_id='(int)$news_id'",dbconnect()); $result = array(); while ($comment = mysql_fetch_array($comment_req)) { $result[] = $comment; } return $result; } function insert_comment($comment) { mysql_query("INSERT INTO commentaires SET news_id='{(int)$comment['news_id']}', auteur='".mysql_real_escape_string($comment['auteur'])."', texte='".mysql_real_escape_string($comment['texte'])."', date=NOW()" ,dbconnect() ); }

myview.php
<html> <head> <title>Les news</title> </head> <body> <h1>Les news</h1> <div id="news"> <h2><?php echo $news['titre'] ?> poste le <?php echo $news['date'] ?></h2> <p><?php echo $news['texte_nouvelle'] ?> </p> <h3><?php echo $nbre_comment ?> commentaires relatifs cette nouvelle</h3> <?php foreach ($comments AS $comment) {?> <h3><?php echo $comment['auteur'] ?> a crit le <?php echo $comment['date'] ?></h3> <p><?php echo $comment['texte'] ?></p> <?php } ?> <form method="POST" action="<?php echo $_SERVER['SCRIPT_NAME'] ?>" name="ajoutcomment"> <input type="hidden" name="news_id" value="<?php echo $news['id']?>"> <input type="text" name="auteur" value="Votre nom"><br /> <textarea name="texte" rows="5" cols="10">Saisissez votre commentaire</textarea><br /> <input type="submit" name="submit" value="Envoyer"> -4Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

myview.php

</form> </div> </body> </html>

mycontroller.php
<?php require ('mymodel.php'); if ($_SERVER['REQUEST_METHOD'] == 'POST') { insert_comment($_POST); header("HTTP/1.1 301 Moved Permanently"); header("location: {$_SERVER['SCRIPT_NAME']}?news_id={$_POST['news_id']}"); exit; } else { $news = get_news($_GET['news_id']); $comments = get_comments($_GET['news_id']); require ('myview.php'); } ?>

Et voil, on a appliqu le modle MVC. On a bien spar le code en 3 couches distinctes, qui se connaissent l'une l'autre. Dans ce code-l, on peut facilement changer la manire d'accder aux donnes (changer de SGBD, par exemple), sans pour autant se soucier le moins du monde de la prsentation, ou de la manipulation future de ces donnes. Remarquez aussi que nous n'avons pas utilis la programmation oriente objet. Voil l'intrt principal d'un modle MVC: sparer les couches de conception, de manire ce que plusieurs groupes de personnes puissent travailler chacun sur sa couche, sans mme qu'ils connaissent les personnes qui utilisent la couche du dessous (ou du dessus, ou d' cot). Il n'est cependant pas toujours facile de bien distinguer les couches, et le motif MVC reste sans aucun doute un motif complexe car, nous allons le voir, on peut fortement le complexifier avec MVC2, mais les dveloppeurs habitus ce modle apprcient particulirement la lisibilit du code. 3 couches sont un minimum, MVC2 en implmente minimum 4 et on peut mme en distinguer jusqu' 5 voire 6 ou plus sur des gros projets. Mais comme toujours, la sparation des entits logiques, ralisable grce la programmation oriente objet, simplifie et clarifie la conception d'un logiciel (et dans notre cas d'une application web). Il est plus facile de dire de quoi est constitue une vinaigrette lorsque les ingrdients sont tous poss sur la table, plutot que d'essayer d'analyser leur mlange au fond du saladier. Il n'y a pas proprement parler de nombre de classes dfini, MVC est un design pattern architectural, c'est un ensemble de principes suivre l'intrieur duquel un grand nombre d'autres motifs de conception interviennent. On peut ainsi crer "plein de" motifs MVCs, chacun rpondra un problme particulier. Cependant la plupart du temps, les developpeurs utiliseront des modles MVC dja crits, dans des frameworks ayant fait leurs preuves.

-5Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

II - Principe du modle MVC


Le but de MVC est de sparer les couches d'une application (en 3 couches distinctes, au minimum, et le plus souvent). On va donc distinguer : 1 2 3 Le modle qui encapsule la logique mtier et la manipulation des sources de donnes. Ici, des designs patterns peuvent intervenir : TableDataGateway, ActiveRecord .... La vue : prsente les donnes au client les demandant (un utilisateur humain ou un autre programme). Ici aussi on peut introduire des motifs : Factory , Composite, TemplateView; par exemple Le contrleur : c'est tout le reste, c'est lui qui analyse la requte du client, accde aux donnes, formate le tout et l'envoie la partie vue qui va prsenter tout a.

On va dtailler un peu, la vue d'abord, c'est un TemplateView. On utilise PHP lui-mme pour crire nos variables dans du HTML, ou alors un moteur de template. Le TransformView peut aussi tre utilis pour sortir en transformant les donnes renvoyes par les modles, qui sont en XML, grce XSLT et les feuilles de style XSL. Une sortie en PDF peut aussi tre utilise ou encore une prsentation JSON des donnes, dont les clients javascript et Ajax sont trs friands. Il est trs important de noter que la vue ne fait que prsenter des donnes et aucun moment elle ne connait leur provenance. C'est le modle qui va fournir toutes les mthodes ncessaires la rcupration, et le contrleur qui se chargera de cette rcupration et de sa transformation ventuelle afin de coller la vue. Du cot du modle, il est trs important que celui-ci ne connaisse ni les contrleurs, ni les vues. Les liens vont des contrleurs vers le modle, de temps en temps, des vues vers le modle (on va voir a), mais jamais dans le sens inverse. Le modle tant totalement indpendant du reste, il pourra faire l'objet d'une rflexion et d'un dveloppement part. Il pourra de mme tre utilis par d'autres composants, tels que des webservices ou d'autres applications locales. Les donnes manipules par le modle doivent persister entre toutes les requtes HTTP, ainsi un support de stockage devra tre utilis. Dans la majeure partie des cas, la source de donnes est une base de donnes relationnelle et le mapping objet relationnel ( ORM) pourra tre utilis, ou l'ActiveRecord, ce qui ne fait pas l'objet de cet article. Il est possible que la vue accde au modle. C'est un choix architectural qui devra tre bien rflchi, car il impose un plus fort couplage et un mlange des couches. On appelle a l'approche pull. C'est souvent rserv aux oprations lgres, comme par exemple afficher une liste de catgories d'lments quelconques ; et aux oprations de lecture uniquement. L'approche inverse, appele push, interdit la vue d'accder au modle. En gnral, on utilise les 2 choix en mme temps : une instruction de lecture simple (rcuprer la liste des membres) sera demande directement par la vue, ou un de ses sous-composants. En revanche une opration de modification du modle, sera demande par un contrleur. Modle MVC global :

-6Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

MVC gnral Diagramme de squence d'un MVC simple :

MVC details

-7Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

Et on arrive enfin au contrleur, c'est un peu l'objet de cet article, car c'est lui le composant principal du modle MVC. Il agit avec le modle, la vue et d'autres contrleurs tout la fois. Quel qu'il soit, le contrleur reoit et analyse la requte du client, accde au modle, et prsente la vue.

-8Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

III - Le frontController ou contrleur frontal


Il existe plusieurs motifs associs au contrleur. Le PageController impose un contrleur par page. C'est le schma 'logique' qui nous vient l'esprit, l'exemple montr plus haut implmente cette ide. De manire simple nous avons spar les 3 couches, et chaque action raliser va se trouver dans un fichier distinct, par exemple post_comment.php , read_new.php ; etc...

Le contrleur doit donc :


1 2 3

Analyser la requte, soit extraire les informations dans l'URL Faire une mise jour du modle si ncessaire, en lui passant des paramtres Dterminer la vue afficher et demander son affichage

Chaque contrleur regroupe l'ensemble des responsabilits dans un seul fichier appel dans l'URL, c'est le motif le plus clair et le plus facile mettre en uvre, la POO n'tant pas ncessaire. Cependant dans des applications qui gagnent un peu en complexit, de la factorisation s'impose et de nouveaux rles vont alors apparaitre: Le FrontController, ou contrleur frontal, est un motif qui est destin prendre en charge l'analyse de la requte client. Il est donc le seul et unique point d'entre de l'application et va orchestrer toute la suite. C'est un singleton, gnralement invoqu dans index.php, et on lui fournit les actions demandes dans l'URL : http://monsite.com/index.php?action=show_livres&categorie=x ou pour faire plus joli avec de la rcriture d'URL : http://monsite.com/livres/show/categorie/x Le site tant en gnral plus complexe que a, l'url intgrera aussi ce qu'on appelle un module : http://monsite.com/bibliotheque/livres/show/categorie/x. Notez que le mapping entre l'URL et le systme MVC sousjascent peut lui aussi devenir une rsponsabilit et tre reprsenter sous forme "d'objets de routage". FrontController est associe au design pattern Command qui va utiliser des objets "$request" et "$response" pour reprsenter l'entre et la sortie du systme. Cette caractristique est commune tout systme MVC bas sur le motif FrontController. La classe Request est en charge de l'analyse de l'URL fournie et elle va dterminer un module, une action, des paramtres. Le FrontController appelle alors le fichier correspondant l'action (motif Command), et va invoquer sa mthode launch(). L'action va tre excute. A la fin, l'action demande le rendu d'une vue via render(), puis son affichage via printOut(), mais elle peut aussi demander une redirection grce redirect(), ou passer la main une autre action avec forward(). classe Request
<?php class Request { public function getParam($key) { return filter_var($this->getTaintedParam($key), FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES); } public function getTaintedParam($key) { if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST[$key])){ return $_POST[$key]; }else{ return $_GET[$key]; } } public function route() { $requestUri = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'],'/'.basename(__FILE__)) + strlen('/'.basename(__FILE__)) ); -9Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

classe Request

if (empty($requestUri)) return array(); $path = parse_url($requestUri, PHP_URL_PATH); preg_match('#^(/(?P<module>\w+))(/(?P<action>\w+)/?)?$#', $path, $matches); $args = explode('&', parse_url($requestUri, PHP_URL_QUERY)); $matches['args'] = $args; return $matches;

classe Response
<?php class Response { private $_vars = array(); private $_headers = array(); private $_body; public function addVar($key, $value) { $this->_vars[$key] = $value; } public function getVar($key) { return $this->_vars[$key]; } public function getVars() { return $this->_vars; } public function setBody($value) { $this->_body = $value; } public function redirect($url, $permanent = false) { if ($permanent){ $this->_headers['Status'] = '301 Moved Permanently'; }else{ $this->_headers['Status'] = '302 Found'; } $this->_headers['location'] = $url; } public function printOut() { foreach ($this->_headers as $key => $value) { header($key. ':' . $value); } echo $this->_body; }

classe frontController
class FrontController { private $_defaults = array('module' => 'index', 'action' => 'index'); private $_request; private $_response; private static $_instance = null;

- 10 Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

classe frontController

private function __construct() { $this->_request = new Request(); $this->_response = new Response(); } public static function getInstance() { if (is_null(self::$_instance)){ self::$_instance = new self(); } return self::$_instance; } public function dispatch($defaults = null) { $parsed = $this->_request->route(); $parsed = array_merge($this->_defaults, $parsed); $this->forward($parsed['module'], $parsed['action']); } public function forward($module, $action) { $command = $this->_getCommand($module, $action); $command->launch($this->_request, $this->_response); } private function _getCommand($module, $action) { if(!file_exists($path = "$module/$action.php")){ throw new Exception("Commande inconnue $module/$action.php"); } require($path); $class = $action.'Action'; return new $class($this); } public function getResponse() { return $this->_response; } public function redirect($url) { $this->_response->redirect($url); } public function render($file) { $view = new View(); $this->_response->setBody($view->render($file,$this->_response->getVars())); }

classe View
class View { public function render($file, $assigns = array()) { extract($assigns); ob_start(); require($file); $str = ob_get_contents(); ob_end_clean(); return $str; } }

- 11 Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

classe Action
abstract class Action { protected $_controller; public function __construct($controller) { $this->_controller = $controller; } abstract public function launch(Request $request, Response $response); public function render($file) { $this->_controller->render($file); } public function printOut() { $this->_controller->getResponse()->printOut(); } protected function _forward($module, $action) { $this->_controller->forward($module, $action); } protected function _redirect($url) { $this->_controller->redirect($url); }

index (main)
$front = frontController::getInstance()->dispatch();

Le code est dj plus complexe, on est pass de l'objet. On le pilotera de cette manire : une commande quelconque
<?php public function launch(Request $request, Response $response) { $variable = 'essai de variable'; $response->addVar('unevariable',$variable); $this->render(dirname(__FILE__).'/show.php'); $this->printOut(); } }

show.php
<?php echo $unevariable ?>

C'est rapide, mais c'est destin vous faire intgrer ce concept de sparation des rles, c'est a qui est important dans MVC. Il ne sert rien d'avoir une structure telle que celle-ci, car en fait apache peut aiguiller lui-mme les requtes grce au mod_rewrite et tout le code peut tre crit de manire procdurale. En fait, le code objet crit plus haut montre globalement le principe utilis dans la plupart des frameworks, ceuxci s'efforcent en plus de rajouter un vrai plus la structure : Zend_Controller_Router_Rewrite, par exemple, est un composant de routage intgr au Zend Framework, qui va bien plus loin que le mod _rewrite d'Apache, en permettant d'crire la vole certaines URLs de manire totalement personnalise, en n'importe quel point du site.
- 12 Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

Ce n'est pas le seul ajout qui y est fait. Le frontController fonctionne de mche aussi avec le motif InterceptingFilter, qui fait partie du design plus global ChainOfAction. Ce motif permet de centraliser toutes les actions qui sont communes chaque requte : vrification d'identit de la personne, affichage du header du site... Le contrleur frontal recevant toutes les requtes, il est facile d'y intgrer des traitements qui se rptent pour toutes les requtes. Exemple interceptingFilter
<?php class FrontController { private $_filters = array(); public function addFilter(Filterable $filter) { $this->_filters[] = $filter; } public function dispatch($defaults = null) { //... foreach($this->_filters AS $filter) { $filter->preFilter(); } $this->forward($parsed['module'], $parsed['action']); foreach(array_reverse($this->_filters) AS $filter) { $filter->postFilter(); }

interface Filterable
interface Filterable { public function preFilter(); public function postFilter(); }

- 13 Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

IV - Motif actionController
Nous venons de voir le fonctionnement d'un frontController, associ au motif command : Le frontController dclenche la mthode launch() du fichier action trouv. Il est possible de factoriser encore un peu plus le traitement, en implmentant les ActionController. Ils ont pour but de regrouper toutes les actions faisant rfrence une mme entit logique sur le site. Une partie de la logique du frontController est alors intgre dans les actionController, qui il passe l'objet de requte et l'objet de rponse. Un tage de plus s'est cre, ce qui permet d'y voir rellement plus clair dans notre code et le cheminement de nos actions, on peut aussi intgrer la gestion des codes http avec la gestion des exceptions, etc ... Ici, nous arrivons un niveau de difficult de conception qui impose l'orientation objet du code, afin d'en tirer toute sa puissance. Mais mesure que la conception se complique, l'utilisation du modle objet, elle, devient tout de suite simple et claire.

Diagramme de squence du MVC ActionController classe frontController


abstract class FrontController { public static function dispatch() { try{ $request = new Request(); $response = new Response(); ActionController::process($request, $response)->printOut(); }catch (Exception $e){ ActionController::processException($request, $response, $e)->printOut(); } } }

classe ActionController
class ActionController

- 14 Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

classe ActionController
{ protected $_request; protected $_response; protected $_redirected; public static function process(Request $request, Response $response) { if (!file_exists($path = 'controllers/' . $request->getParam('controller') .'.php')){ throw new ControleurIntrouvableException ('contrleur introuvable'); } require_once($path); $class = $request->getParam('controller') . 'Controller'; $controller = new $class($request, $response); return $controller->launch(); } public static function processException(Request $request, Response $response, Exception $e) { $controller = new self($request, $response); return $controller->launchException($e); } public function __construct(Request $request, Response $response) { $this->_request = $request; $this->_response = $response; $this->_redirected = false; } private function _actionExists($action) { try{ $method = new ReflectionMethod(get_class($this),$action); return ($method->isPublic() && !$method->isConstructor()); }catch (Exception $e){ return false; } } public function redirect($url) { if ($this->_redirected == true){ throw new Exception('Une redirection a dja t demande'); } $this->_response->redirect($url); $this->_redirected = true; } private function _render($file) { $view = new View(); $this->_response->setBody($view->render(dirname(__FILE__) . '/views/' . $file, $this>_response->getVars())); } public function __get($param) { return $this->_response->getVar($param); } public function __set($name,$param) { $this->_response->addVar($name, $param); } public function launch() { $action = $this->_request->getParam('action'); if (!$this->_actionExists($action)){ throw new ActionIntrouvableException('Action introuvable'); - 15 Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

classe ActionController

} // prefiltering $this->$action(); // postfiltering if (!$this->_redirected){ $this->_render($this->_request->getParam('action') . '.php'); } return $this->_response;

public function launchException(Exception $e) { if ($e instanceof MVCException){ $this->_render('404.php'); }else{ $this->_render('500.php'); } return $this->_response; }

classes d'Exception
class ActionIntrouvableException extends MVCException { } class ControleurIntrouvableException extends MVCException { } class MVCException extends Exception { }

index (main)
$front = frontController::dispatch();

Ca se complique encore, on voit premire vue que le rle du frontController est rduit un simple bloc try - catch. Une grosse partie de la logique de controle a t dporte dans l'ActionController, dont tous les contrleurs applicatifs hriteront. La partie vue est simplifie ici. Grace aux mthodes magiques __get et __set, le contrleur peut assigner directement une valeur la vue via $this->unePropriete. C'est un systme que l'on retrouve souvent. Souvent aussi, la gestion des vues est un peu plus complexe, avec des Factory et Composite, on peut alors arriver un diagramme de squence qui ressemble a :

- 16 Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

MVC actionController + ViewFactory A titre informatif, on peut regarder le diagramme de flux du modle MVC du Zend Framework :

- 17 Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

Zend Framework MVC

- 18 Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

Le modle MVC et le contrleur sous PHP par Julien Pauli (Tutoriels, article et confrences PHP et developpement web) (Blog)

V - Conclusions
Nous venons de voir un petit bout du motif MVC, notamment la partie contrleur en liaison avec beaucoup de Design Patterns connus. Pour un site rapide, petit, ou n'tant pas amen voluer rapidement, un tel motif peut s'avrer lourd en gestion. D'autant plus qu'Apache + PHP permettent dj pas mal de libert. Sur une application plus complexe, en revanche, dvelopper au sein d'un Framework tel que Zend Framework ou Symfony permettra de produire du code plus clair, de sparer chaque rle de votre application, de programmer plusieurs (les rgles tant communes) et de faire voluer trs simplement le code, pour peu que celui-ci ait t pens convenablement ses dbuts. Ceci permet aussi de garder en tte le cheminement des requtes, de travailler avec des diagrammes, de simplifier indirectement la gestion de projet. Alors que PHP tait l'origine conu comme un langage "glue", le modle objet de PHP5 alli la puissance interne de PHP montre bien que celui-ci est autant capable que Java, .NET, Ruby ou autre, en terme de conception et d'architecture logicielle. Il faut aussi savoir manger toutes les gamelles, je vous conseille de vous pencher sur Java EE, et ses frameworks MVC, comme Struts par exemple, ou Rails pour Ruby, vous y apprendrez beaucoup de choses. Programmation web/PHP et architecture MVC Implmentation du pattern MVC (Java) Prsentation de tout un tas de Design Pattern (exemples en Java) La rubrique ruby pourrait vous tre utile aussi Notre rubrique conception Notre espace Zend Framework

- 19 Copyright 2007 - Julien Pauli. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://julien-pauli.developpez.com/tutoriels/php/mvc-controleur/

You might also like