Vous êtes sur la page 1sur 44

Rapport:

La mise en place d’une


architecture MVC en PHP.

Nom et prénom: Amine BAJJI


Filière: GINF1
Encadré par: M. Khalid AMECHNOUE

1. Présentation...............................................................................................................................................

1
2. Introduction................................................................................................................................................
3. Création de la base de données................................................................................................................
4. Modèle sans MVC.......................................................................................................................................
4.1. Critique du modèle sans MVC..............................................................................................................
5. Modèle MVC................................................................................................................................................
5.1. Une logique métier...............................................................................................................................
5.2. Présentation du modèle MVC...............................................................................................................
5.3. Rôles des composants.........................................................................................................................
5.4. Interactions entre les composants........................................................................................................
5.5. Mise en place de l’architecture MVC dans l’exemple...........................................................................
5.6. Avantages............................................................................................................................................
Figure 6 : Fichier Modele.php......................................................................................................................
6. Améliorations MVC....................................................................................................................................
6.1. Factorisation des éléments d'affichage................................................................................................
6.2. Application à l’exemple.........................................................................................................................
6.2.1. Principe du modèle de page........................................................................................................
6.2.1. Les fonctions ob_start() et ob_get_clean()..................................................................................
6.3. Factorisation de la connexion à la base de données...........................................................................
6.4. Sous partie controleur : Gestion des erreurs........................................................................................
6.4.1. Modifier le comportement de l’objet PDO....................................................................................
6.4.2. Try-catch.....................................................................................................................................
6.4. Une présentation cohérente à l'utilisateur............................................................................................
6.5. Autres améliorations.............................................................................................................................
6.5.1. La fonction prepare().........................................................................................................................
6.5.1.1. Un outil de sécurité contre l’injection SQL................................................................................
7. Modèle POO................................................................................................................................................
7.1. Passage à un ‘Modele’ orienté objet....................................................................................................
7.2. Technique de “lazy loading” dans notre Modèle:................................................................................
7.3. Passage à une Vue orientée objet.......................................................................................................
7.3.1 Logigramme de Vue.....................................................................................................................
7.4. Passage à un Contrôleur orienté objet.................................................................................................
7.4.1 Contrôleur frontal de index.php vers une classe...........................................................................
7.5. Testons notre blogue............................................................................................................................
7.6. Ajoutons une fonctionnalité..................................................................................................................
7.7. Teste de la fonctionnalité.....................................................................................................................
7.8. Notre architecture finale.......................................................................................................................
Bibliographie...............................................................................................................................................

2
1. Présentation
Ce rapport a pour objectif de présenter la mise en place d'une architecture MVC en
PHP pour un blog contenant des articles. L'architecture MVC est une méthode de
conception logicielle largement utilisée pour développer des applications Web en
utilisant le langage de programmation PHP. Elle permet une séparation claire des
responsabilités entre les différentes parties d'une application et offre une meilleure
maintenabilité, évolutivité et extensibilité.

2. Introduction
Le développement d'une application Web en utilisant le langage de programmation
PHP peut être une tâche complexe, surtout lorsque l'application est volumineuse et
que les différentes parties de l'application sont interdépendantes. L'architecture
MVC (Modèle-Vue-Contrôleur) en PHP a été créée pour résoudre ce problème en
séparant clairement les responsabilités des différentes parties de l'application.

Dans ce rapport, nous allons présenter la mise en place d'une architecture MVC en
PHP pour un blog contenant des articles. Le modèle représentera les données du
blog, la vue sera responsable de la présentation des articles aux visiteurs, et le
contrôleur gérera la communication entre le modèle et la vue en utilisant le langage
de programmation PHP.

Nous allons examiner chaque partie de l'architecture en détail, en expliquant son


rôle et en présentant les outils et les technologies utilisés pour la mise en place de
l'architecture MVC en PHP. Nous présenterons également les avantages et les
inconvénients de l'utilisation de cette architecture pour le développement d'une
application Web en PHP.

3. Création de la base de données


Pour mettre en place notre architecture MVC pour le blog, nous avons créé une
base de données MySQL en utilisant les commandes SQL nécessaires. Nous avons
créé deux tables : T_BILLET pour stocker les billets et T_COMMENTAIRE pour
stocker les commentaires associés à chaque billet. La table T_BILLET contient les
colonnes BIL_ID, BIL_DATE, BIL_TITRE et BIL_CONTENU. La colonne BIL_ID est
une clé primaire qui s'auto-incrémente à chaque nouvel enregistrement. La table
3
T_COMMENTAIRE contient les colonnes COM_ID, COM_DATE, COM_AUTEUR,
COM_CONTENU et BIL_ID. La colonne COM_ID est une clé primaire auto-
incrémentale et la colonne BIL_ID est une clé étrangère qui référence la colonne
BIL_ID de la table T_BILLET pour établir la relation entre les commentaires et les
billets. Ensuite, nous avons inséré des données de test dans la base de données en
utilisant les requêtes SQL appropriées. Nous avons créé deux billets avec leurs titres
et leur contenu, et nous avons ajouté deux commentaires associés au premier billet.

4. Modèle sans MVC

4
4.1. Critique du modèle sans MVC
Le code présenté est un code PHP utilisant une connexion directe à la base de
données pour récupérer des données et les afficher sur une page web. Il n'utilise
pas l'architecture MVC (Modèle-Vue-Contrôleur) qui est une approche de conception
de logiciels permettant de séparer la logique métier de la présentation.
Le principal problème de ce modèle est qu'il n'y a pas de séparation claire des
responsabilités. La logique métier et la présentation sont toutes deux intégrées dans
le code PHP, ce qui peut rendre le code difficile à maintenir et à évoluer à mesure
que les exigences du projet évoluent.

Les principaux défauts de cette page Web sont les suivants :


❖ Elle mélange balises HTML et code PHP ;
❖ Sa structure est monobloc, ce qui rend sa réutilisation difficile.
5
De manière générale, tout logiciel doit gérer plusieurs problématiques :
❖ Interactions avec l'extérieur, en particulier l'utilisateur : saisie et contrôle de
données, affichage. C'est la problématique de présentation ;
❖ Opérations sur les données (calculs) en rapport avec les règles métier («
business logic »). C'est la problématique des traitements ;
❖ Accès et stockage des informations qu'il manipule, notamment entre deux
utilisations. C'est la problématique des données.
La page Web actuelle mélange code de présentation (les balises HTML) et accès
aux données (requêtes SQL). Ceci est contraire au principe de responsabilité
unique. Ce principe de conception logicielle est le suivant : afin de clarifier
l'architecture et de faciliter les évolutions, une application bien conçue doit être
décomposée en sous-parties, chacune ayant un rôle et une responsabilité
particuliers. L'architecture actuelle montre ses limites dès que le contexte se
complexifie. Le volume de code des pages PHP explose et la maintenabilité devient
délicate. Il faut faire mieux.

5. Modèle MVC
5.1. Une logique métier
La logique métier est l'ensemble des règles, procédures et calculs spécifiques à une
entreprise ou une organisation qui sont nécessaires pour accomplir ses activités
principales et atteindre ses objectifs. Elle est souvent formalisée dans des
documents tels que des manuels ou des cahiers des charges et est utilisée pour
guider le développement de logiciels ou de systèmes informatiques qui automatisent
ou soutiennent les processus métier. Dans le modèle MVC, la logique métier est une
partie importante du modèle, car il est responsable de la gestion des données et de
la logique métier de l'application.

5.2. Présentation du modèle MVC


Le modèle MVC est un modèle d'architecture logicielle utilisé dans le
développement de nombreuses applications Web modernes. Ce modèle divise
l'application en trois parties principales:
❖ la partie Modèle ;
❖ la partie Vue ;
❖ la partie Contrôleur.

Le modèle MVC facilite le développement, la maintenance et l'extension de


l'application en séparant clairement les préoccupations et les responsabilités de
chaque composant. Ce modèle est largement utilisé dans des applications de
commerce électronique, des applications de médias sociaux et des applications de
gestion de contenu.

6
5.3. Rôles des composants
La partie Modèle d'une architecture MVC encapsule la logique métier ainsi que
l'accès aux données.
Il peut s'agir d'un ensemble de fonctions (Modèle procédural) ou de classes (Modèle
orienté objet).
La partie Vue s'occupe des interactions avec l'utilisateur : présentation, saisie et
validation des données.
La partie Contrôleur gère la dynamique de l'application. Elle fait le lien entre
l'utilisateur et le reste de l'application.

5.4. Interactions entre les composants


Dans le modèle MVC, chaque composant interagit avec les deux autres
composants pour assurer le fonctionnement de l'application. Voici comment les
composants interagissent les uns avec les autres :
❖ La demande de l'utilisateur (exemple : requête HTTP) est reçue et interprétée
par le Contrôleur.
❖ Celui-ci utilise les services du Modèle afin de préparer les données à afficher.
❖ Ensuite, le Contrôleur fournit ces données à la Vue, qui les présente à
l'utilisateur (par exemple sous la forme d'une page HTML).

Figure 4 : Interactions des composants MVC

5.5. Mise en place de l’architecture MVC dans l’exemple


Dans l'exemple que vous avez donné, il s'agit de diviser le code d'un site web en
trois fichiers distincts : un fichier "Modele.php" qui va gérer l'accès aux données de
la base de données, un fichier "vueAccueil.php" qui va gérer l'affichage des billets

7
du blog, et un fichier "index.php" qui va faire le lien entre les deux pages
précédentes.
Cette approche de la programmation est appelée "architecture MVC" (Modèle - Vue
- Contrôleur). Elle consiste à séparer le code en trois parties distinctes :
❖ Le Modèle, qui gère l'accès aux données et la logique métier de l'application
❖ La Vue, qui gère l'affichage des données à l'utilisateur
❖ Le Contrôleur, qui fait le lien entre le Modèle et la Vue, et qui gère les actions
de l'utilisateur (comme l'envoi d'un formulaire, par exemple).
Cette approche permet de faciliter la maintenance du code, de le rendre plus lisible
et plus facile à comprendre, et de le rendre plus facilement évolutif.

index.php

index.php
Modele.php
vueAccueil.php

5.6. Avantages
le design pattern MVC (Modèle-Vue-Contrôleur) est conçu pour répondre aux
principes suivants:

● Le principe de "responsabilité unique" stipule qu'une classe ou une fonction


ne doit avoir qu'une seule responsabilité. Cela signifie qu'une classe ou une
fonction ne devrait être responsable que d'une seule tâche ou d'un seul
comportement. En respectant ce principe, il est plus facile de comprendre et
de modifier le code, et les erreurs sont moins susceptibles de se produire.
● Le principe de "couplage faible" vise à minimiser les dépendances entre les
différentes parties d'un programme. Cela signifie que les modules d'un
programme doivent être conçus de manière à ce que les changements
apportés à l'un n'affectent pas les autres. Le couplage faible permet de

8
faciliter la maintenance du code, de rendre le code plus réutilisable et de le
rendre plus facilement testable.
● Le principe de "cohésion forte" indique que les éléments d'un module ou d'une
classe doivent être étroitement liés et contribuer à la même fonctionnalité.
Cela signifie que les éléments qui ne sont pas directement liés à la fonction
principale de la classe ou du module doivent être déplacés ailleurs. Une forte
cohésion facilite la compréhension et la modification du code, et réduit le
risque d'erreurs.

9
Figure 6 : Fichier Modele.php

6. Améliorations MVC
6.1. Factorisation des éléments d'affichage
La factorisation des éléments d'affichage communs est une technique qui consiste à
regrouper les éléments d'affichage qui sont utilisés dans plusieurs parties d'une
application et à les placer dans un fichier ou une classe distincte. Cela permet de
réduire la duplication de code et de faciliter la maintenance.
Par exemple, si une application web a plusieurs pages qui utilisent le même en-tête
et le même pied de page, il peut être utile de créer un fichier distinct pour ces
éléments d'affichage et de les inclure dans chaque page. De cette façon, si l'on doit
apporter des modifications à l'en-tête ou au pied de page, il suffit de le faire une
seule fois dans le fichier distinct plutôt que de le modifier sur chaque page.
La factorisation des éléments d'affichage communs peut également s'appliquer à
d'autres parties de l'application, comme les formulaires, les boutons, les messages
d'erreur, etc. En regroupant ces éléments dans des fichiers ou des classes

10
distinctes, on peut améliorer la cohérence de l'interface utilisateur et faciliter la
maintenance du code.
En résumé, la factorisation des éléments d'affichage communs est une technique
qui permet de réduire la duplication de code et de faciliter la maintenance en
regroupant les éléments d'affichage communs dans des fichiers ou des classes
distinctes.

6.2. Application à l’exemple

6.2.1. Principe du modèle de page


Le principe du modèle de page, ou template, consiste à créer une structure de base
pour toutes les pages d'un site web, avec des éléments communs tels que l'en-tête,
le menu de navigation et le pied de page, et à y intégrer le contenu spécifique à
chaque page. Cela permet de faciliter la création et la maintenance du site, en
évitant la duplication de code et en garantissant une cohérence visuelle sur toutes
les pages.
Le modèle de page est généralement écrit en HTML, avec des balises spéciales
pour les zones variables qui seront remplacées par le contenu spécifique à chaque
page. Par exemple, on peut utiliser des balises PHP pour inclure le contenu d'une
page spécifique dans une zone définie du modèle.

En utilisant le principe du modèle de page (ou template), on peut diviser la page


vueAccueil en deux parties distinctes :
❖ Le gabarit : c'est la structure de base de la page, qui contient les éléments
communs à toutes les pages du site web, tels que l'en-tête, le menu de
navigation et le pied de page. Cette structure est généralement fixe et ne
change pas souvent.
❖ Le contenu dynamique : c'est la partie variable de la page, qui contient le
contenu spécifique à la page vueAccueil, tel que la liste des billets du blog.
Cette partie du code est dynamique et peut varier selon les pages.

11
vueAccueil.php

vueAcuceil.php
gabarit.php

Partie statique
Partie dynamique

$titre $conten
u
Dans la plupart des sites web dynamiques, le titre de la page est souvent généré
dynamiquement en fonction de la page affichée ou des données qui y sont
présentées.
Le titre de la page est donc dynamisé pour permettre de l'adapter à chaque page
affichée. Cela se fait en utilisant une variable $titre qui contient le titre spécifique de
chaque page et qui est insérée dans la balise <title> du template à l'aide de la
fonction echo.

12
6.2.1. Les fonctions ob_start() et ob_get_clean()
● La fonction ob_start() est utilisée pour activer la temporisation de sortie
(output buffering) dans le but de stocker temporairement les données
envoyées à la sortie (comme les résultats de la requête SQL) dans une
mémoire tampon, avant de les envoyer au navigateur.

Cela permet de stocker temporairement les résultats et d'insérer facilement


les éléments d'affichage communs (en-tête, pied de page, etc.) sans avoir à

13
les répéter sur chaque page. Une fois les éléments communs ajoutés, la
mémoire tampon est vidée et le contenu spécifique de chaque page est
ajouté à la suite.
● La fonction ob_get_clean() est une fonction PHP qui permet de récupérer le
contenu de la mémoire tampon de sortie (output buffer en anglais), de vider la
mémoire tampon et de désactiver la mise en tampon de la sortie.

Page générée
du script ob_start()
stockage

Mémoire tampon
ob_get_clean()
vide la mémoire
tampon et
Page générée récupère la
du script page générée.

Utilisée

Page 1 Page 3
Page 2
Sans l'utilisation de la fonction ob_start(), la factorisation des éléments d'affichage
communs ne fonctionnerait pas car les éléments inclus avec la fonction include
seraient affichés directement à l'écran au lieu d'être stockés dans une variable.
L'utilisation de la fonction ob_start() permet de mettre en tampon la sortie de PHP
avant de l'afficher à l'écran. Ainsi, les éléments inclus avec la fonction include sont
stockés dans une variable plutôt que d'être affichés directement à l'écran, ce qui
permet de les manipuler avant de les afficher ou de les stocker dans une variable.

6.3. Factorisation de la connexion à la base de données


La factorisation de la connexion à la base de données est une technique qui
consiste à regrouper le code de connexion à la base de données dans un fichier ou

14
une classe distincte afin de réduire la duplication de code et de faciliter la
maintenance.

La fonction getBdd() retourne une instance de l'objet PDO connecté à la base de


données. Cette fonction est appelée par la fonction getBillets() pour récupérer la
connexion à la base de données avant d'exécuter une requête SQL qui récupère les
billets du blog. Les résultats de la requête sont ensuite retournés par la fonction
getBillets().

6.4. Sous partie controleur : Gestion des erreurs

6.4.1. Modifier le comportement de l’objet PDO


La gestion des erreurs dans le contrôleur est une pratique importante pour assurer
la robustesse et la fiabilité de l'application. Les erreurs peuvent survenir à différentes
étapes du traitement des données, depuis la récupération des données de la base
de données jusqu'à l'affichage des résultats à l'utilisateur final.
En effet, par défaut, PDO ne lance pas d'exception en cas d'erreur mais retourne
simplement une valeur qui peut être fausse, ce qui peut rendre le débogage difficile. En
activant le mode exception, PDO lancera une exception PDOException lorsqu'une erreur
survient, ce qui permet de récupérer plus facilement les erreurs et de les traiter de manière
appropriée dans le code.
En définissant PDO::ATTR_ERRMODE à PDO::ERRMODE_EXCEPTION, les
erreurs sont signalées sous forme d'exceptions, ce qui permet d'améliorer la gestion
des erreurs dans le code.

15
La valeur par défaut de l'attribut PDO::ATTR_ERRMODE est
PDO::ERRMODE_SILENT, ce qui signifie que les erreurs sont silencieuses et ne
sont pas signalées par PDO.

6.4.2. Try-catch
❖ Le bloc "try" contient le code qui doit être exécuté et qui peut lever une
exception. Si une exception est levée, le code est interrompu et l'exécution
passe au premier bloc "catch" correspondant à l'exception levée.
❖ Le bloc "throw" permet de lever une exception en créant un objet de type
"Exception" ou une sous-classe de cette dernière, avec des informations sur
l'erreur rencontrée.
❖ Le bloc "catch" permet de capturer l'exception et de gérer l'erreur. Il peut y
avoir plusieurs blocs "catch" pour gérer différentes exceptions.
❖ L'objet "Exception" contient des informations sur l'erreur levée, comme son
message, son code d'erreur et sa trace d'exécution. Ces informations sont
accessibles dans le bloc "catch" via l'objet "Exception" passé en argument.

16
17
6.4. Une présentation cohérente à l'utilisateur
Dans le cadre d'une application web, il est important de toujours maintenir une
présentation cohérente à l'utilisateur, même en cas d'erreur. Pour cela, il est courant
de créer une vue dédiée à l'affichage des erreurs, par exemple nommée
"vueErreur.php".
Cette vue peut contenir des informations sur l'erreur survenue (message d'erreur,
code d'erreur, etc.) et permettre à l'utilisateur de revenir à la page précédente ou à
l'accueil du site.

6.5. Autres améliorations


La page respecte désormais un modèle MVC simple. L'ajout de nouvelles
fonctionnalités se fait maintenant en trois étapes : écrire les fonctions d'accès aux
données dans le modèle, créer une nouvelle vue utilisant un gabarit pour afficher les

18
données, puis ajouter une page contrôleur pour lier le modèle et la vue. Pour rendre
le contexte d'exemple plus réaliste, le clic sur le titre d'un billet de blog doit
désormais afficher sur une nouvelle page le contenu et les commentaires associés à
ce billet. Pour répondre à ce nouveau besoin, le modèle et la vue nécessaires sont
ajoutés, et un nouveau fichier contrôleur est créé. La vue de la page d'accueil est
également modifiée pour ajouter un lien vers la page billet.php. Le résultat obtenu
est une présentation harmonieuse.

6.5.1. La fonction prepare()


Lorsque on utilise la méthode prepare() de l'objet PDO, on stocke une requête
préparée dans un objet PDOStatement. Cette requête préparée contient des
paramètres qui peuvent être remplacés par des valeurs réelles lors de l'exécution de
la requête.
Pour remplacer ces paramètres par des valeurs réelles, vous utilisez les méthodes
bindParam() ou bindValue() de l'objet PDOStatement. Ces méthodes vous
permettent de lier une valeur à un paramètre dans la requête.
Ensuite, vous exécutez la requête préparée en appelant la méthode execute() de
l’objet PDOStatement. Cette méthode exécute la requête en remplaçant les
paramètres par les valeurs réelles que vous avez liées à l'aide des méthodes
bindParam() ou bindValue().

6.5.1.1. Un outil de sécurité contre l’injection SQL


L'approche de la requête préparée (utilisant la méthode prepare() de PDO) consiste
à séparer la requête SQL en deux parties :
1. La requête SQL statique : cette partie de la requête contient la structure de la
requête SQL telle que les noms de colonnes, les noms de tables, les mots-
clés tels que SELECT, FROM, WHERE, etc. Cette partie ne varie pas d'une
exécution de la requête à l'autre.
2. La requête SQL dynamique : cette partie de la requête contient les valeurs
que l'on veut insérer ou récupérer dans la base de données. Cette partie peut
varier d'une exécution de la requête à l'autre.
Au lieu d'insérer directement les valeurs dans la requête SQL, la requête préparée
permet de lier les variables dynamiques à la requête statique en utilisant des
paramètres.
Le mécanisme de préparation permet de préparer la requête SQL en deux temps :
1. La requête SQL statique est envoyée au serveur de base de données, qui
l'analyse et la prépare pour l'exécution.
2. La requête SQL dynamique est liée à la requête préparée en utilisant les
paramètres. Cela permet de s'assurer que les valeurs sont traitées de
manière sûre et sécurisée, et empêche les injections SQL.
La sécurité contre les injections SQL est assurée par le mécanisme de liage des
paramètres à la requête préparée. Les valeurs fournies par l'utilisateur sont

19
considérées comme des données et non comme des instructions SQL, et ne sont
pas interprétées par le serveur de base de données comme telles. Cela empêche
les attaques par injection SQL car même si un attaquant essaie d'insérer des
instructions SQL malveillantes dans les valeurs fournies, ces instructions ne seront
pas interprétées par le serveur de base de données.

7. Modèle POO
Rappelons qu’on a un modèle et un contrôleur, on souhaite les écrire en modèle
POO.

20
On peut facilement créer des classes métier modélisant pour modéliser les entités

21
7.1. Passage à un ‘Modele’ orienté objet

La modélisation présentée pour les classes Billet, Commentaire et Modele est


conforme au principe de la cohésion forte. Chaque classe a une seule
responsabilité, avec des méthodes spécifiques à sa tâche respective. De plus, la
relation de cohérence logique entre les méthodes et les attributs de chaque classe
renforce la cohésion interne de chaque classe.

22
7.2. Technique de “lazy loading” dans notre Modèle:
Dans notre modèle, nous avons utilisé la technique du chargement tardif pour
retarder l'instanciation de l'objet qui gère l'accès à la base de données. Plus
précisément, nous avons utilisé une variable de classe nommée "$bdd" qui est
initialisée à NULL lors de la création de l'objet et qui est instanciée à la première
utilisation de la méthode "getBdd()".
La méthode "getBdd()" est utilisée pour accéder à l'objet qui gère l'accès à la base
de données. Lorsqu'elle est appelée, la méthode vérifie si l'objet "$bdd" a déjà été
instancié. Si ce n'est pas le cas, la méthode instancie un nouvel objet PDO, qui est
ensuite assigné à la variable "$bdd".
Cette technique permet de retarder l'instanciation de l'objet PDO jusqu'à ce qu'il soit
réellement nécessaire, c'est-à-dire jusqu'à ce qu'une requête SQL soit exécutée.
Cela peut améliorer les performances de l'application en évitant de charger toutes
les données associées à une entité donnée lorsqu'elle est chargée pour la première
fois.
l'abstraction a été un élément clé pour la mise en place de la technologie lazy
loading dans notre modèle. Elle nous a permis de masquer les détails
23
d'implémentation de l'accès à la base de données en fournissant une interface de
haut niveau pour les classes métiers, tout en mettant en place la technique du
chargement tardif pour économiser des ressources système et améliorer les
performances de l'application. La méthode abstraite "getBdd()" a été utilisée pour
retarder l'instanciation de l'objet PDO jusqu'à ce qu'il soit réellement nécessaire. En
utilisant l'abstraction, nous avons pu rendre notre modèle plus modulaire, plus facile
à maintenir et plus évolutif.

7.3. Passage à une Vue orientée objet


Rappelons que le répertoire Vue contiendra les fichiers vueAccueil.php,
vueBillet.php et vueErreur.php, ainsi que la page commune gabarit.php.

● Le premier problème de cette approche concerne les appels aux fonctions


PHP ob_start et ob_get_clean qui sont dupliqués. Ces fonctions sont utilisées
pour mettre en tampon (buffer) la sortie (output) générée par le script PHP,
afin de la manipuler avant de la renvoyer au client. Cependant, si ces
fonctions sont utilisées plusieurs fois dans le code, cela peut provoquer des
erreurs et une perte de performances.
● Le deuxième problème est que la génération des fichiers vue, y compris dans
le contrôleur, utilise directement la fonction PHP require, sans protection
contre une éventuelle absence du fichier demandé. Cela peut entraîner des
erreurs fatales si un fichier vue est manquant ou mal nommé. De plus, cela
rend le code moins robuste et difficile à maintenir.

24
25
26
● Solution:
Maintenant qu’on a identifié ces problèmes, il est possible de proposer une
solution. La solution consiste à utiliser une classe Vue qui encapsule la
génération des fichiers vue et l'utilisation des fonctions ob_start et
ob_get_clean. La classe Vue peut également inclure des protections
contre les erreurs de chargement de fichiers vue, ainsi que d'autres
fonctionnalités utiles pour la gestion des vues dans l'application.

27
28
La classe Vue est une solution qui permet de résoudre les deux problèmes
précédemment mentionnés. Elle offre une encapsulation de la génération des
fichiers vue et gère la temporisation de sortie avec ob_start() et ob_get_clean().
Elle prend en compte également la protection contre l'absence du fichier demandé,
en levant une exception si le fichier n'existe pas.
La classe Vue a une méthode constructeur qui prend en paramètre l'action, qui
détermine le nom du fichier vue à utiliser. Elle a également une méthode generer()
qui génère et affiche la vue, en utilisant la méthode genererFichier() qui génère le
contenu de la vue en utilisant les données passées en paramètre.
La méthode genererFichier() utilise la fonction file_exists() pour vérifier si le fichier
demandé existe et lance une exception s'il n'existe pas. Elle utilise également
ob_start() pour démarrer la temporisation de sortie, et ob_get_clean() pour
renvoyer le tampon de sortie généré par l'inclusion du fichier vue.
En utilisant cette classe, on évite la duplication des appels aux fonctions ob_start()
et ob_get_clean() et on protège contre les erreurs d'absence de fichier demandé.

7.3.1 Logigramme de Vue


Début
|
V
Générer la partie spécifique de la vue en appelant la méthode genererFichier avec le nom
du fichier de la vue et les données associées
|
V
Récupérer le contenu généré dans la variable $contenu
|
V
Générer le gabarit commun en appelant la méthode genererFichier avec le nom du fichier du
gabarit, le titre de la vue et le contenu généré
|
V
Récupérer la vue générée dans la variable $vue
|
V
Afficher la vue en envoyant son contenu au navigateur
|
V
Fin
l'instanciation de chaque vue est faite au niveau du contrôleur. Le contrôleur crée
une instance de la classe Vue correspondant à l'action demandée, puis il appelle la
méthode "generer" de cette instance pour générer et afficher la vue correspondante.
C'est pourquoi la création d'une instance de la classe Vue apparaît dans le
logigramme du contrôleur.

29
La deuxième instance étape consiste pour chaque vue à définir la variable $this-
>titre qui sera utilisée dans le gabarit pour afficher le titre de la page
correspondante. De plus, il faut supprimer les appels aux fonctions PHP de
temporisation.

L'affichage d'une vue se fera désormais en instanciant un objet de la classe Vue,


puis en appelant sa méthode generer() !

30
31
32
7.4. Passage à un Contrôleur orienté objet
Notre partie Contrôleur actuelle se compose d'une série d'actions écrites sous la forme de
fonctions et du contrôleur frontal index.php.

● Problèmes du premier modèle du contrôleur


○ Le premier modèle de contrôleur, qui consiste en une série de
fonctions dans un unique fichier, peut présenter des problèmes de
maintenabilité et de lisibilité lorsque le site web s'agrandit et que le
nombre d'actions possibles augmente.
○ En effet, cette approche conduit à un fichier de contrôleur de plus en
plus grand et difficile à gérer. Il devient également complexe de
comprendre les différentes actions possibles, ce qui rend la
maintenance difficile et l'ajout de nouvelles fonctionnalités laborieuses.
● Solution
○ Pour remédier à ces problèmes, une solution plus modulaire est de
répartir les actions dans plusieurs classes contrôleur, en fonction du
contexte associé aux actions. Par exemple, une classe
ContrôleurAccueil pourra être créée pour gérer l'affichage de la page
d'accueil, tandis qu'une classe ContrôleurBillet sera dédiée à
l'affichage des billets.
○ Cette approche présente l'avantage de favoriser la lisibilité et la
maintenabilité du code, en permettant une meilleure organisation des
fonctionnalités par contexte. De plus, elle facilite l'ajout de nouvelles
fonctionnalités en répartissant le travail sur plusieurs classes, plutôt
que de devoir modifier un unique fichier de contrôleur.

33
34
Chaque classe contrôleur instancie les classes modèle requises, puis utilise leurs
méthodes pour récupérer les données nécessaires aux vues. La méthode generer
de la classe Vue définie plus haut est utilisée en lui passant en paramètre un tableau
associatif contenant l'ensemble des données nécessaires à la génération de la vue.
Chaque élément de ce tableau est constitué d'une clé (entre apostrophes) et de la
valeur associée à cette clé.

7.4.1 Contrôleur frontal de index.php vers une classe


Dans un modèle MVC, le contrôleur frontal joue un rôle clé dans le traitement des requêtes
entrantes. Cependant, lorsqu'il s'agit de gérer un grand nombre d'actions, cette structure
peut rapidement devenir difficile à maintenir.
Une solution consiste à utiliser une classe Routeur pour gérer la répartition des requêtes
vers les différents contrôleurs et leurs actions associées. La méthode principale du routeur
peut analyser la requête entrante pour déterminer quelle action doit être exécutée.
En répartissant les actions dans différentes classes contrôleur, nous améliorons la
cohérence de notre code en séparant les responsabilités. En utilisant une classe routeur,
nous pouvons également améliorer la maintenabilité du code en réduisant la complexité du
contrôleur frontal.

35
● Ce code définit une classe Routeur qui permet de gérer les différentes
requêtes entrantes (requêtes HTTP envoyées au serveur par le client
(navigateur web) pour demander une ressource ou une action).
● Les trois premières lignes font appel aux fichiers ControleurAccueil.php,
ControleurBillet.php et Vue.php, qui contiennent les classes
ContrôleurAccueil, ContrôleurBillet et Vue, respectivement. Ces fichiers
doivent être inclus pour pouvoir utiliser ces classes.
● La classe Routeur contient deux propriétés privées : $ctrlAccueil et $ctrlBillet,
qui sont des instances de ControleurAccueil et de ControleurBillet,
respectivement. Ces propriétés sont initialisées dans le constructeur de la
classe.
● La méthode publique routerRequete() analyse la requête entrante et
détermine l'action à entreprendre en fonction des paramètres de la requête
GET. Si l'action est "billet", elle appelle la méthode billet() de l'objet $ctrlBillet,
qui prend en paramètre l'identifiant du billet à afficher. Sinon, si aucune action
n'est définie, elle appelle la méthode accueil() de l'objet $ctrlAccueil, qui
affiche la page d'accueil du site. Si l'action n'est pas valide, elle génère une
exception avec le message "Action non valide".
● La méthode privée erreur() permet d'afficher une vue spécifique en cas
d'erreur. Elle crée un objet Vue avec le titre "Erreur" et appelle la méthode
generer() de cet objet en lui passant un tableau associatif contenant le
message d'erreur.
● En résumé, cette classe Routeur permet de gérer les différentes requêtes
entrantes en redirigeant vers les contrôleurs correspondants, qui utiliseront
les classes Modèle et Vue pour générer la réponse appropriée. Cela permet
une meilleure organisation du code et facilite la maintenance du site web.

7.5. Testons notre blogue


Visitons le lien: http://localhost/MiseEnPlaceMVC/MVCOOP/index.php

36
7.6. Ajoutons une fonctionnalité.
Avec cette nouvelle architecture, l'ajout de nouvelles fonctionnalités est plus simple
et modulaire, car chaque fonctionnalité est gérée par son propre contrôleur et sa
propre vue.
On souhaite maintenant que l'affichage des détails sur un billet permettra d'ajouter
un nouveau commentaire. Le remplissage des champs Auteur et Commentaire est
obligatoire. Le clic sur le bouton Commenter déclenche l'insertion du commentaire
dans la base de données et la réactualisation de la page Web.
les étapes en résumé pour ajouter la fonctionnalité d'ajout de commentaire :
1. Ajouter une méthode dans la classe Commentaire permettant d'insérer un
nouveau commentaire dans la base de données.
2. Ajouter un formulaire HTML dans la vue d'un billet pour permettre la saisie
d'un nouveau commentaire.
3. Ajouter une méthode dans le contrôleur Billet pour traiter l'action de
soumission du formulaire et appeler le service du modèle pour insérer le
commentaire dans la base de données.
4. Mettre à jour le routeur pour router une requête d'ajout de commentaire vers
la nouvelle méthode du contrôleur.

37
38
7.7. Teste de la fonctionnalité.

39
Pour corriger cette erreur:

Maintenant la fonctionnalité fonctionne:

40
Le commentaire est bien affiché sur le site et ajouté à la base de données

41
7.8. Notre architecture finale

Un schéma résumant le fonctionnement de notre architecture MVC


42
● Dans ce schéma, on peut voir que le navigateur envoie des requêtes HTTP au
routeur qui détermine l'action à effectuer en fonction de l'URL demandée et
des paramètres associés. Le contrôleur est ensuite appelé pour effectuer
l'action demandée.
● Le contrôleur interagit avec le modèle pour récupérer ou modifier des
données. Le modèle utilise la base de données pour stocker les données du
blog. La base de données est également accessible par le contrôleur pour
effectuer des opérations de lecture ou d'écriture.
● Enfin, le contrôleur retourne une réponse HTTP au navigateur qui affiche le
résultat de l'action demandée.

Bibliographie
https://kamechnoue.wordpress.com
43
https://bpesquet.developpez.com/tutoriels/php/evoluer-architecture-mvc/#LI
https://github.com/bpesquet/MonBlog

44

Vous aimerez peut-être aussi