6.4.2 Un exemple complet de saisie et validation de données Montrons pour conclure ce chapitre comment réaliser une fonctionnalité complète MVC, incluant une partie Modèle pour communiqu
Trang 1/ / P a r c o u r s d e s a t t r i b u t s p o u r c r é e r l a r e q u ê t e
f o r e a c h ( $ t h i s−>schema a s $nom => $ o p t i o n s ) {
/ / L i s t e d e s noms d ’ a t t r i b u t s + l i s t e d e s v a l e u r s (
a t t e n t i o n a u x ’ )
$noms = $ v i r g u l e $nom ;
$ v a l e u r = $ t h i s−>bd−>prepareChaine ( $ t h i s −>donnees [ $nom ] ) ;
$ v a l e u r s = $ v i r g u l e " ’ $ v a l e u r ’ " ;
/ / A p a r t i r d e l a s e c o n d e f o i s , on s é p a r e p a r d e s v i r g u l e s
$ v i r g u l e = " , " ;
}
$ r e q u e t e = " INSERT INTO $ t h i s−>nom_table ( $noms ) VALUES (
$ v a l e u r s ) " ;
$ t h i s−>bd−>execRequete ( $ r e q u e t e ) ;
}
La fonction de mise à jour est similaire ; je vous laisse la consulter dans le code lui-même Nous voici équipés avec un cadre pré-établi pour réaliser la partie Modèle d’une application Outre l’intérêt de disposer de fonctionnalités prêtes à l’emploi,
ce qui peut déjà économiser du développement, cette approche a aussi le mérite de normaliser les méthodes de programmation, avec gain de temps là encore quand on consulte le code
6.4.2 Un exemple complet de saisie et validation de données
Montrons pour conclure ce chapitre comment réaliser une fonctionnalité complète MVC, incluant une partie Modèle pour communiquer avec la base de données L’exemple choisi est celui de l’inscription d’un internaute sur le site On demande de saisir ses données personnelles dans un formulaire, y compris un mot de passe d’accès
au site, pour lequel on demande une double saisie La validation de ce formulaire entraîne une insertion dans la base La figure 6.8 montre le formulaire d’inscription
Figure 6.8 — Formulaire d’inscription sur le site
Trang 2Le contrôleur en charge des fonctionnalités d’inscription est inscription L’ac-tion par défaut (index) affiche le formulaire de la figure 6.8 Voici son code
f u n c t i o n i n d e x ( )
{
/ / On a f f e c t e l e t i t r e e t on c h a r g e l e c o n t e n u
$ t h i s−>vue−>t i t r e _ p a g e = " I n s c r i p t i o n " ;
$ t h i s−>vue−> s e t F i l e ( " contenu " , " i n s c r i p t i o n t p l " ) ;
/ / On i n s t a n c i e l a c l a s s e TableBD s u r ’ I n t e r n a u t e ’
$ t b l _ i n t e r = new I n t e r n a u t e ( $ t h i s−>bd ) ;
/ / P r o d u c t i o n du f o r m u l a i r e e n i n s e r t i o n
$ t h i s−>vue−>f o r m u l a i r e = $ t b l _ i n t e r −>f o r m u l a i r e ( TableBD : :
INS_BD ,
" i n s c r i p t i o n " , " e n r e g i s t r e r " ) ;
echo $ t h i s−>vue−>r e n d e r ( " page " ) ;
}
On instancie un objet $tbl_inter de la classe Internaute (le fichier
Internaute.php se trouve dans application/modeles) Cette classe est une sous-classe de
TableBD, hérite de toutes ses fonctionnalités et en redéfinit quelques-unes pour
s’adapter aux spécificités de manipulation des données de la table Internaute.
La première particularité est le constructeur Comme on sait sur quelle table s’appuie la classe, on peut passer son nom « en dur » au constructeur de TableBD,
ce qui donne le code ci-dessous
c l a s s I n t e r n a u t e e x t e n d s TableBD
{
/ / Le c o n s t r u c t e u r d e l a c l a s s e On a p p e l l e
/ / s i m p l e m e n t l e c o n s t r u c t e u r d e l a s u p e r −c l a s s e
/ / e n l u i p a s s a n t l e nom d e l a t a b l e v i s é e
f u n c t i o n _ _ c o n s t r u c t ( $bd )
{
/ / A p p e l du c o n s t r u c t e u r d e IhmBD
p a r e n t : : _ _ c o n s t r u c t ( " I n t e r n a u t e " , $bd ) ;
}
La seconde particularité est le formulaire de saisie On ne peut pas se contenter
du formulaire générique proposé par TableBD car il faut demander deux fois le mot
de passe à l’utilisateur afin d’avoir confirmation qu’il n’a pas commis d’erreur de saisie Il faut donc redéfinir dans Internaute la méthode Formulaire() qui vient remplacer (« surcharger » est le terme juste) celle héritée de TableBD Nous avons déjà vu à plusieurs reprises comment produire des formulaires de saisie, je vous laisse consulter cette méthode dans le code
Rappelons que dans une application de base de données, une grande partie des
formulaires est destinée à effectuer des opérations d’insertion ou de mise à jour sur
les tables Bien entendu, il faut éviter d’utiliser un formulaire distinct pour chacune
Trang 3de ces opérations et nous utilisons donc la technique détaillée dans le chapitre 2, page 78, pour adapter la présentation des champs en fonction du type d’opération effectué
Passons à la mise à jour Ici encore les fonctions génériques fournies par TableBD
ne suffisent pas C’est notamment le cas de la méthode controle() qui comprend de nombreux contrôles complémentaires de ceux effectués dans la méthode générique
La complémentarité implique que la méthode de la super-classe doit être appelée en
plus des contrôles ajoutés dans la méthode spécialisée Cela se fait en plaçant
expli-citement un appel parent::controle dans le code, comme montré ci-dessous :
f u n c t i o n c o n t r o l e ( )
{
/ / I n i t i a l i s a t i o n d e l a l i s t e d e s m e s s a g e s d ’ e r r e u r
$ t h i s−> e r r e u r s = a r r a y ( ) ;
/ / On v é r i f i e q u e l e s c h a m p s i m p o r t a n t s o n t é t é s a i s i s
i f ( $ t h i s−>donnees [ ’ e m a i l ’ ]== " " )
$ t h i s−> e r r e u r s [ ] = " Vous d e v e z s a i s i r v o t r e e−mail ! " ;
e l s e i f ( ! $ t h i s−>c o n t r o l e E m a i l ( $ t h i s −>donnees [ ’ e m a i l ’ ] ) )
$ t h i s−> e r r e u r s [ ] = " V o t r e e−mail d o i t ê t r e de l a forme
xxx@yyy [ z z z ] ! " ;
/ / C o n t r ô l e s u r l e mot d e p a s s e
i f ( i s S e t ( $ t h i s−>donnees [ ’ mot_de_passe ’ ] ) ) {
i f ( $ t h i s−>donnees [ ’ mot_de_passe ’ ]== " "
o r $_POST [ ’ c o n f _ p a s s e ’ ]== " "
o r $_POST [ ’ c o n f _ p a s s e ’ ] != $ t h i s−>donnees [ ’ mot_de_passe ’ ] )
$ t h i s−> e r r e u r s [ ] = " Vous d e v e z s a i s i r un mot de p a s s e " " e t l e c o n f i r m e r à l ’ i d e n t i q u e ! " ;
}
i f ( ! i s S e t ( $ t h i s−>donnees [ ’ r e g i o n ’ ] ) or empty ( $ t h i s −>donnees [
’ r e g i o n ’ ] ) )
$ t h i s−> e r r e u r s [ ] = " Vous d e v e z s a i s i r v o t r e r é g i o n ! " ;
i f ( $ t h i s−>donnees [ ’ a n n e e _ n a i s s a n c e ’ ]== " " )
$ t h i s−> e r r e u r s [ ] = " V o t r e année de n a i s a n c e e s t
i n c o r r e c t e ! " ;
i f ( $ t h i s−>donnees [ ’ prenom ’ ]== " " )
$ t h i s−> e r r e u r s [ ] = " Vous d e v e z s a i s i r v o t r e prénom ! " ;
i f ( $ t h i s−>donnees [ ’nom ’ ]== " " )
$ t h i s−> e r r e u r s [ ] = " Vous d e v e z s a i s i r v o t r e nom ! " ;
/ / A p p e l a u x c o n t r ô l e s d e l a m é t h o d e g é n é r i q u e
p a r e n t : : c o n t r o l e ( ) ;
i f ( c o u n t ( $ t h i s−> e r r e u r s ) > 0) {
r e t u r n f a l s e ;
}
e l s e {
r e t u r n t r u e ;
}
}
Trang 4On peut toujours ajouter ou raffiner des contrôles Vous pouvez vous reporter
à la section consacrée à la validation des formulaires, page 86, pour un exposé des différentes vérifications nécessaires
Une autre méthode modifiée par rapport à la méthode générique est insertion() Le seul ajout est le hachage du mot de passe avec la fonction MD5, afin de ne pas l’insérer en clair dans la base
f u n c t i o n i n s e r t i o n ( )
{
/ / On i n s è r e l e mot d e p a s s e h a c h é
$ t h i s−>donnees [ ’ mot_de_passe ’ ] = md5 ( $ t h i s −>donnees
[ ’ m o t _ d e _ p a s s e ’ ] ) ;
/ / I l n e r e s t e p l u s qu ’ à a p p e l e r l a m é t h o d e d ’ i n s e r t i o n
h é r i t é e
p a r e n t : : i n s e r t i o n ( ) ;
}
Pour finir, voici l’action enregistrer du contrôleur Inscription C’est cette action qui est appelée quand on valide le formulaire
f u n c t i o n e n r e g i s t r e r ( )
{
/ / I d e m q u e p r é c é d e m m e n t
$ t h i s−>vue−>t i t r e _ p a g e = " R é s u l t a t de v o t r e i n s c r i p t i o n " ;
$ t b l _ i n t e r = new I n t e r n a u t e ( $ t h i s−>bd ) ;
/ / On c r é e un o b j e t à p a r t i r d e s d o n n é e s du t a b l e a u HTTP
$ t b l _ i n t e r−>nouveau ($_POST) ;
/ / C o n t r ô l e d e s v a r i a b l e s p a s s é e s e n POST
i f ( $ t b l _ i n t e r−>c o n t r o l e ( ) == f a l s e ) {
$ m e s s a g e s = $ t b l _ i n t e r−>m e s s a g e s ( ) ;
/ / E r r e u r d e s a i s i e d é t e c t é e : on a f f i c h e l e m e s s a g e
/ / e t on r é a f f i c h e l e f o r m u l a i r e a v e c l e s v a l e u r s s a i s i e s
$ t h i s−>vue−>contenu = " <b> $ m e s s a g e s < / b>\n "
$ t b l _ i n t e r−>f o r m u l a i r e ( TableBD : : INS_BD ,
" i n s c r i p t i o n " , " e n r e g i s t r e r " ) ; }
e l s e {
/ / On v a q u a n d même v é r i f i e r q u e c e t e m a i l n ’ e s t p a s d é j à / / i n s é r é
i f ( $ i n t e r = $ t b l _ i n t e r−>c h e r c h e L i g n e ($_POST) ) {
$ t h i s−>vue−>contenu = "Un i n t e r n a u t e avec c e t e m a i l
e x i s t e d é j à "
$ t b l _ i n t e r−>f o r m u l a i r e ( TableBD : : INS_BD , " i n s c r i p t i o n " ,
" e n r e g i s t r e r " ) ; }
e l s e {
$ t b l _ i n t e r−> i n s e r t i o n ( ) ;
Trang 5/ / M e s s a g e d e c o n f i r m a t i o n
$ t h i s−>vue−>contenu = " Vous ê t e s bien e n r e g i s t r é avec
l ’ e m a i l "
" <b> $ t b l _ i n t e r−>email </ b > Bienvenue ! < br / > "
" Vous p o u v e z m a i n t e n a n t v o u s c o n n e c t e r au s i t e " ; }
}
/ / F i n a l e m e n t , on a f f i c h e l a v u e comme d ’ h a b i t u d e
echo $ t h i s−>vue−>r e n d e r ( " page " ) ;
}
Après initialisation d’une instance de la classe Internaute, l’action débute par l’exécution de la méthode controle() Si une erreur est détectée, un message est constitué et on réaffiche le formulaire en reprenant, pour valeurs par défaut, les saisies présentes dans le tableau $_POST Sinon, on vérifie que l’e-mail n’existe pas déjà, puis
on insère
6.4.3 Pour conclure
Ce dernier exemple a montré de manière complète l’interaction des trois composants
du MVC La structuration en contrơleurs et actions permet de situer facilement le déroulement d’une suite d’actions (ici, saisie, mise à jour) et fournit une initialisation
de l’environnement (comme la connexion à la base) qui épargne au programmeur les instructions répétitives La vue est en charge de la sortie HTML, et on constate que les actions ne contiennent plus aucune balise HTML Le modèle, au moins dans la prise en compte de la persistance, fournit encore des fonctionnalités toutes prêtes qui limitent la taille du code et facilitent sa compréhension
Convaincu(e) ? Comme tout concept un peu avancé, le MVC demande un peu
de pratique et un délai d’assimilation Cet effort en vaut vraiment la peine, et ce chapitre avait pour but de vous proposer une introduction la plus douce possible, tout
en montrant une implantation réaliste Prenez le temps d’analyser soigneusement la fonctionnalité d’inscription pour bien comprendre les interactions entre les différents composants Le découpage induit par le MVC est logique, cohérent, et mène à des fragments de code tout à fait maỵtrisables par leur taille et leur complexité limitée
Le reste du site est constitué d’actions qui peuvent s’étudier isolément, indépen-damment les unes des autres et indépenindépen-damment du contexte MVC Encore une fois, récupérez le code du site, étudiez-le et modifiez-le Quand vous aurez assimilé les
principes, vous pourrez passer à des fonctionnalités plus poussées et à des frameworks
de développement plus robustes
En ce qui concerne la complexité du développement MVC, il faut prendre conscience que les objets Internaute manipulés pour l’inscription sont très simples
et correspondent à la situation élémentaire ó la correspondance établie par le modèle associe un objet (instance de la classe Internaute) à une seule ligne d’une
table (Internaute) C’est un cas de mapping (correspondance entre deux
représenta-tions) trivial Vous trouverez dans le code du site une version plus complexe d’un