78 Chapitre 2. Techniques de base Est-il nécessaire de préciser qu’il faut rester extrêmement prudent avec les don- nées transmises par HTTP ? Il est par exemple très délicat de proposer un formulaire pour saisir des commandes à effectuer, dans MySQL ou dans le système d’exploita- tion. Encore une fois, reportez-vous au site php.net pour sa documentation sur la sécurité des applications PHP, et de nombreuses recommandations à ce sujet. 2.3 MISE À JOUR D’UNE BASE PAR FORMULAIRE L’interface de mise à jour de la table FilmComplet donnéeàlafinduchapitre1 (voir les exemples pages 47 et 49) est assez rudimentaire et ferait rapidement hurler n’importe quel utilisateur. Nous allons développer un système plus convivial pour insérer, mettre à jour ou détruire les lignes d’une table, en prenant comme cible la table FilmSimple, qui est un peu plus facile à manipuler (voir le schéma page 28). 2.3.1 Script d’insertion et de mise à jour Le script principal, FilmSimple.php, affiche une page dont le contenu varie en fonction du mode choisi. Voici les modes possibles : 1. En mode par défaut, on affiche la liste des films en leur associant une ancre permettant d’accéder au formulaire de modification. Une ancre placée sous le tableau permet d’accéder au formulaire d’insertion. 2. En mode modification d’un film, on affiche un formulaire présentant les champs de saisie. Chaque champ vaut par défaut la valeur couramment stockée dans la base pour ce film. Seule exception : on ne peut pas modifier le titre puisqu’on suppose ici que c’est le moyen d’identifier (et donc de retrouver) le film modifié. 3. Enfin, en mode insertion, on présente un formulaire de saisie, sans valeur par défaut. Pour commencer nous allons définir avec define() des constantes définissant les différents modes. Les constantes permettent de manipuler des symboles, plus faciles à utiliser et plus clairs que des valeurs. // Les constantes pour le mode define ("MODE_DEFAUT" , "defaut"); define ( "MODE_INSERTION" , " i n s e r t i o n " ) ; define ("MODE_MAJ", "maj"); Ensuite, afin de ne pas se lancer dans un script d’une taille démesurée, on découpe le travail en plusieurs parties, correspondant chacune à une fonctionnalité précise, puis on réalise chaque partie par une fonction. La première fonction affiche le formulaire. On pourrait prévoir une fonction pour un formulaire en mise à jour et une autre pour un formulaire en insertion, mais la plus grande part du code serait commun, ce qui entraîne une double modification chaque fois que le site évolue (par exemple lors de l’ajout d’un champ dans la table). 2.3 Mise à jour d’une base par formulaire 79 Il est beaucoup plus astucieux de programmer une seule fonction qui affiche un contenu légèrement différent en fonction du type de mise à jour souhaité (insertion ou modification). Voici le code de cette fonction. Le style de programmation adopté ici est du HTML dans lequel on insère ponctuellement des instructions PHP. Ce style trouve très rapidement ses limites en terme de lisibilité, comme vous pourrez vous en convaincre en essayant de décrypter le contenu. Rassurez-vous, c’est la dernière fois que j’utilise cette gestion obscure des accolades ! Exemple 2.16 exemples/FormFilmSimple.php : Le formulaire avec valeurs par défaut, et modes insertion ou mise à jour <?php // Formulaire de saisie , avec valeurs par défaut function FormFilmSimple ($mode, $val_defaut) { ?> <!−− On e s t en HTML −−> <form action=’FilmSimple .php ’ method=’post ’> <input type=’hidden ’ name="action" value="FormFilmSimple"/> <input type=’hidden ’ name="mode" value="<?php echo $mode ?>"/> <table> <?php if ( $mode == MODE_INSERTION) { ? > <tr><td>Titre : </td><td><input type=’ text ’ size=’40 ’ name= ’ titre ’ value="<?php echo $val_defaut [ ’ titre ’]?>"/> </td ></tr > <?php } else {?> <tr ><td>Mise à jour de </td><td ><?php echo $val_defaut [ ’titre ’]?> <input type=’hidden ’ name=’titre ’ value=’<?php echo $val_defaut[ ’ titre ’]?> ’/> </td ></tr > <?php } ?> <tr ><td >Année : </ td > <td><input type=’text ’ size=’4 ’ maxlength=’4 ’ name="annee" value=" <?php echo $val_defaut[ ’annee ’]?>"/> </td ></tr > <tr><td>Réalisateur (prénom − nom) : </ td > <td><input type=’text ’ size=’20 ’ name="prenom_realisateur" value="<?php echo $val_defaut [ ’ prenom_realisateur ’]?>"/> <br/> <input type=text size=’20 ’ name="nom_realisateur" value="<?php echo $val_defaut[ ’ nom_realisateur ’]?>"/> </td ></tr > 80 Chapitre 2. Techniques de base <tr ><td >Année de naissance : <td><input type=’text ’ size=’4 ’ maxlength=’4 ’ name=’annee_naissance ’ value="<?php echo $val_defaut [ ’annee_naissance ’]?>"/> </td ></tr > <tr><td colspan=’2 ’><input type=’submit ’ value=’Exécuter ’/> </td ></tr > </table > </form> <?php } ?> La fonction FormFilmSimple() prend en paramètres le mode (insertion ou modification) et un tableau contenant les valeurs par défaut à placer dans les champs. Le mode est systématiquement placé dans un champ caché pour être transmis au script traitant les données du formulaire, et saura ainsi dans quel contexte elles ont été saisies : <input type=’hidden’name="mode"value="<?php echo $mode ?>"/> Les modes d’insertion et de modification correspondent à deux affichages diffé- rents du formulaire. En insertion le champ « titre » est saisissable et sans valeur par défaut. En mise à jour, il est affiché sans pouvoir être saisi, et il est de plus dans un champ caché avec sa valeur courante qui est transmise au script de traitement des données. <?php if ( $mode == MODE_INSERTION) { ? > <tr><td>Titre : </td><td><input type=’text ’ size=’40 ’ name=’ titre ’ value="<?= $val_defaut [ ’ titre ’]?>"/></td ></tr> <?php } else {?> <tr><td>Mise à jour de </td><td><?= $val_defaut [ ’ titre ’]?></td> <td><input type=’hidden ’ name=’titre ’ value=’<?= $val_defaut[ ’titre ’]?> ’/></td></tr > <?php } ?> Le tableau des valeurs par défaut passé en paramètre à la fonction, $val_defaut, doit contenir un élément par champ, le nom de l’élément étant le nom du champ, et sa valeur la valeur par défaut du champ. Ce tableau associatif peut s’obtenir par un appel à mysql_fetch_assoc() si le film vient de la base et doit être modifié. Il peut également s’agir du tableau $_POST ou $_GET après saisie du formulaire, pour réafficher les données prises en compte. La figure 2.4 montre le formulaire en modification. Notez qu’on place un autre champ caché, action, dans le formulaire. La trans- mission de cette variable action au script FilmSimple.php indique que des valeurs ont 2.3 Mise à jour d’une base par formulaire 81 été saisies dans le formulaire, et qu’elles doivent déclencher une insertion ou une mise à jour dans la base. Figure 2.4 — Formulaire en modification du film Vertigo La seconde fonction effectue les requêtes de mise à jour. Elle prend en entrée le mode (insertion ou modification), un tableau associatif qui, comme $val_defaut, contient les valeurs d’une ligne de la table FilmSimple, enfin l’identifiant de connexion à la base. Exemple 2.17 exemples/MAJFilmSimple.php : Fonction de mise à jour de la table <?php // Fonction de mise à jour ou insertion de la table FilmSimple function MAJFilmSimple ($mode, $film , $connexion) { // Préparation des variables , en traitant par addSlashes // les chaînes de caractères $titre = addSlashes($film [ ’ titre ’ ]) ; $annee = $film [ ’annee ’ ]; $prenom_realisateur = addSlashes($film [ ’ prenom_realisateur ’]) ; $nom_realisateur = addSlashes($film [ ’ nom_realisateur ’]) ; $annee_naissance = $film [ ’annee_naissance ’ ]; if ( $mode == MODE_INSERTION) $requete = "INSERT INTO FilmSimple ( titre , annee , " . "prenom_realisateur , nom_realisateur , annee_naissance) " . " VALUES (’ $titre ’, ’$annee ’, ’$prenom_realisateur ’, " . " ’$nom_realisateur ’, ’$annee_naissance ’)" ; else 82 Chapitre 2. Techniques de base $requete = "UPDATE FilmSimple SET annee=’$annee ’ , " . "prenom_realisateur=’$prenom_realisateur ’, " . "nom_realisateur=’$nom_realisateur ’ , " . "annee_naissance=’$annee_naissance ’ " ."WHEREtitre=’$titre’"; // Exécution de l ’ordre SQL ExecRequete ($requete , $connexion) ; } ?> Enfin, la troisième fonction affiche un tableau des films présents dans la table, en associant à chaque film une ancre pour la modification. Exemple 2.18 exemples/TableauFilms.php : Tableau affichant la liste des films <?php // Affichage du tableau des films function TableauFilms ($connexion) { $ r e su l t a t = ExecRequete ( "SELECT ∗ FROM FilmSimple" , $connexion) ; echo "<table border=’4’ cellspacing =’2’ cellpadding=’2’>" . "<caption align =’bottom’>Table <i>FilmSimple </i ></caption > " . "<tr><th>Titre </th><th>Année</th><th>Réalisateur </th>" . "<th>Année naissance </th><th>Action</th></tr>\n" ; while ($film = ObjetSuivant ( $resultat )) { // On code le titre pour le placer dans l ’URL $titreURL = urlEncode ($film−>titre); echo "<tr><td>$film−>titre </td><td>$film−>annee </td> " . "<td>$film−>prenom_realisateur $film−>nom_realisateur </td> " . "<td>$film−>annee_naissance </td> " . "<td><a href =’FilmSimple .php?mode=" . MODE_MAJ . "& titre=$titreURL’>Modifier ce film </a></td></tr >\n" ; } echo "</table>\n"; } ?> Le tableau est standard, la seule particularité se limite à une l’ancre qui contient deux arguments, le mode et le titre du film à modifier : <a href=’FilmSimple.php?mode=maj&titre=$titreURL’> Rappelons qu’il faut prendre garde à ne pas placer n’importe quelle chaîne de caractères dans une URL (voir page 67) : des caractères blancs ou accentués seraient sans doute mal tolérés et ne donneraient pas les résultats escomptés. On ne doit . les différents modes. Les constantes permettent de manipuler des symboles, plus faciles à utiliser et plus clairs que des valeurs. // Les constantes pour le mode define ("MODE_DEFAUT" , "defaut"); define. la liste des films en leur associant une ancre permettant d’accéder au formulaire de modification. Une ancre placée sous le tableau permet d’accéder au formulaire d’insertion. 2. En mode modification. d’identifier (et donc de retrouver) le film modifié. 3. Enfin, en mode insertion, on présente un formulaire de saisie, sans valeur par défaut. Pour commencer nous allons définir avec define() des constantes