IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Les formulaires et PHP5

Date de publication : 30 juillet 2006 , Date de mise à jour : 11 septembre 2006


II. Vision d'ensemble
II-A. Partie HTML : le formulaire lui-même
Obligatoire : la balise <form>
Fondamental : les contrôles <input>, <textarea>, <select> etc.
Facultatif mais pratique : <fieldset>, <legend> et <label>
II-B. Partie PHP : traitement du formulaire
Les superglobales $_GET, $_POST et $_FILES
Les variables


II. Vision d'ensemble

Je pense qu'il est nécessaire de commencer par voir tous les aspects d'un formulaire. Nous reviendrons par la suite sur les éléments les uns après les autres. Nous allons commencer par les formulaires eux-mêmes, côté HTML, puis nous verrons rapidement comment recevoir les informations d'un formulaire avec PHP.


II-A. Partie HTML : le formulaire lui-même


Obligatoire : la balise <form>

Un formulaire est une balise HTML contenant des éléments permettant à un utilisateur de saisir des informations.
Formulaire minimum : form.php
<form method="post" action="form.php">
    <input type="submit" value="Envoyer" />
</form>
La balise <form> est invisible à l'internaute. Elle sert uniquement à indiquer au navigateur Web qu'il a affaire à un formulaire. Nous pouvons voir ici les deux paramètres les plus courants : "method" et "action".

Propriétés de la balise <form>
  • action
    Sa valeur détermine l'adresse du script qui recevra le contenu du formulaire, une fois transmis.
    Cet attribut est requis.
  • enctype
    Sa valeur détermine le type de données envoyées par le formulaire : sont-ce seulement des informations textuelles ou bien y a-t-il également des fichiers joints ?
    Cet attribut est optionnel et vaut "application/x-www-form-urlencoded" par défaut. Si l'on souhaite envoyer des fichiers en plus de texte, il faut donner la valeur "multipart/form-data".
  • id
    Sa valeur est utilisée pour les manipulations du DOM (Document Object Model) à l'aide d'un script comme ECMAScript (alias JavaScript ou JScript, dans le cas du Web).
  • method
    Les valeurs peuvent être "get" ou bien "post".
    Cet attribut est optionnel et vaut "get" s'il est omis.
Quelle que soit la méthode de soumission choisie, le formulaire enverra ses informations à une page de destination spécifiée grâce à la propriété action.

Les deux méthodes de soumision de formulaires
  • GET : Les variables sont transmises par l'URL, ce qui les rend visibles et modifiables très simplement par l'internaute.
  • POST : Les variables sont transmises de manière cachée : c'est généralement la méthode préférée des développeurs.
info Au cours de ce tutoriel, j'utiliserai exclusivement la méthode POST car c'est la plus courante.
Un formulaire a généralement pour vocation de permettre à l'internaute de saisir des informations. La plus connue des balises permettant d'y parvenir s'appelle <input>.


Fondamental : les contrôles <input>, <textarea>, <select> etc.

Les contrôles sont les éléments HTML qui permettent de saisir des informations. Il en existe trois différents : input, textarea et select.
La balise input a une signification très simple : elle permet de "saisir" des informations.

La forme que prend cette balise est définie par la propriété 'type' :
  • text : Permet d'obtenir une petite boîte de saisie de texte dans la page HTML
  • submit : Envoie le formulaire
  • reset : Rétablit le formulaire à son état d'origine
  • radio : Permet d'obtenir une liste dont un seul choix est possible ; il faut utiliser plusieurs boutons radio du même nom (propriété name) pour que cela soit utile
  • password : Même principe que text, prévu pour les mots de passe : le texte n'est pas affiché clairement lors de la saisie
  • image : Même principe que submit mais c'est une image au lieu d'un bouton
  • hidden : Même principe que text mais celui-ci n'est pas affiché du tout dans la page
  • file : Affiche un bouton permettant de sélectionner un fichier de l'ordinateur ; la plupart des navigateurs l'accompagnent d'une case de texte contenant le chemin d'accès au fichier
  • checkbox : Permet d'obtenir une case à cocher
  • button : Simplement un bouton ayant la même allure que submit ou reset, mais celui-ci n'a pas d'utilité propre
Formulaire mixte : form.php
  1. <form method="POST" action="test.php" enctype="multipart/form-data"> 
  2.     text : 
  3.     <input type="text" name="text" /><br /> 
  4.  
  5.     password : 
  6.     <input type="password" name="password" /><br /> 
  7.  
  8.     checkbox : 
  9.     <input type="checkbox" name="checkbox_1" checked="checked" /> 
  10.     <input type="checkbox" name="checkbox_2" /> 
  11.     <input type="checkbox" name="checkbox_3" /><br /> 
  12.  
  13.     radio : 
  14.     <input type="radio" name="radio" checked="checked" /> 
  15.     <input type="radio" name="radio" /> 
  16.     <input type="radio" name="radio" /><br /> 
  17.  
  18.     file : 
  19.     <input type="file" name="file" /><br /> 
  20.  
  21.     textarea : 
  22.     <textarea name="textarea" cols="20" rows="7"></textarea><br /> 
  23.  
  24.     select : 
  25.     <select name="select"> 
  26.         <option value="Option 1">Option 1</option> 
  27.         <option value="Option 2">Option 2</option> 
  28.         <option value="Option 3">Option 3</option> 
  29.     </select><br /> 
  30.  
  31.     <input type="hidden" name="hidden" /><br /> 
  32.     <input type="image" src="http://www.developpez.net/forums/images/logo16.gif" /><br /> 
  33.     <input type="button" value="Bouton inutile" /><br /><br /> 
  34.  
  35.     <input type="submit" value="Envoyer" /> 
  36.     <input type="reset" value="Rétablir" /> 
  37. </form> 
Nous pouvons noter que les contrôles actifs (les boutons) portent une valeur (le texte à afficher), tandis que les contrôles de saisie (les autres) portent un nom. Nous verrons plus tard qu'ils peuvent également porter une valeur.
L'élément textarea permet de saisir du texte sur plusieurs lignes, ce qui est impossible avec input type="text".
Un select est une alternative intéressante à des boutons radio s'il y a plus de trois choix possibles ou bien si le nombre de choix est dynamique.

info Il peut y avoir un ou plusieurs submit par formulaire. Tous auront le même effet : soumettre le formulaire au script défini dans la propriété form action="".
idea Essayez ce formulaire avec la méthode POST puis la méthode GET pour voir la différence.

Facultatif mais pratique : <fieldset>, <legend> et <label>

L'élément fieldset permet de regrouper les contrôles par thème. Utilisé conjointement à un élément legend, cela permet d'obtenir un formulaire structuré (à la fois dans le code et visuellement dans le navigateur).
Exemple de fieldset+legend : form.php
  1. <form method="post" action="form.php"> 
  2.     <fieldset> 
  3.         <legend>Informations personnelles</legend> 
  4.         Prénom : <input type="text" name="first_name" /><br /> 
  5.         Nom : <input type="text" name="last_name" /><br /> 
  6.     </fieldset> 
  7.     <fieldset> 
  8.         <legend>Informations virtuelles</legend> 
  9.         Pseudonyme : <input type="text" name="nickname" /><br /> 
  10.         Site Web : <input type="text" name="website" /><br /> 
  11.         Messagerie instantanée : <input type="text" name="instant_messenger" /><br /> 
  12.     </fieldset><br /> 
  13.  
  14.     <input type="submit" value="Envoyer" /> 
  15.     <input type="reset" value="Rétablir" /> 
  16. </form> 
Chaque fieldset ne contient qu'un seul legend mais peut contenir plusieurs contrôles. Il est possible d'assigner un élément label à chaque contrôle de la manière suivante :
Exemple de label: form.php
  1. <form method="post" action="form.php"> 
  2.     <fieldset> 
  3.         <legend>Informations personnelles</legend> 
  4.         <label> 
  5.             Prénom : <input type="text" name="first_name" /> 
  6.         </label><br /> 
  7.         <label> 
  8.             Nom : <input type="text" name="last_name" /> 
  9.         </label><br /> 
  10.     </fieldset> 
  11.     <fieldset> 
  12.         <legend>Informations virtuelles</legend> 
  13.         <label> 
  14.             Pseudonyme : <input type="text" name="nickname" /> 
  15.         </label><br /> 
  16.         <label> 
  17.             Site Web : <input type="text" name="website" /> 
  18.         </label><br /> 
  19.         <label> 
  20.             Messagerie instantanée : <input type="text" name="instant_messenger" /> 
  21.         </label><br /> 
  22.     </fieldset> 
  23.     <fieldset> 
  24.         <legend>Fichiers joints</legend> 
  25.         <label> 
  26.             Fichier 1 : <input type="file" name="file_1" /> 
  27.         </label><br /> 
  28.         <label> 
  29.             Fichier 2 : <input type="file" name="file_2" /> 
  30.         </label><br /> 
  31.     </fieldset><br /> 
  32.  
  33.     <input type="submit" value="Envoyer" /> 
  34.     <input type="reset" value="Rétablir" /> 
  35. </form> 
Cet exemple est identique au précédent à un détail près : si l'on clique sur un label, le curseur est maintenant déplacé dans le contrôle associé.

info Il est possible d'associer les labels et les contrôles d'une autre manière (explicitement avec la propriété "for") mais c'est moins intuitif et cela peut entrer en conflit avec certaines de vos habitudes de programmation, dans la mesure où cela fait intervenir la propriété "id" de votre contrôle. Cela permet de placer les labels où on le souhaite dans le formulaire. Bien entendu, rien ne vous empêche de répéter les labels.
Exemple d'association explicite : form.php
  1. <form method="post" action="form.php"> 
  2.     <ul> 
  3.         <li>Informations personnelles 
  4.             <ul> 
  5.                 <li><label for="first_name">Prénom</label></li> 
  6.                 <li><label for="last_name">Nom</label></li> 
  7.             </ul> 
  8.         </li> 
  9.         <li>Informations virtuelles 
  10.             <ul> 
  11.                 <li><label for="nickname">Pseudonyme</label></li> 
  12.                 <li><label for="website">Site Web</label></li> 
  13.                 <li><label for="instant_messenger">Messagerie instantanée</label></li> 
  14.             </ul> 
  15.         </li> 
  16.         <li>Fichiers joints 
  17.             <ul> 
  18.                 <li><label for="file_1">Fichier 1</label></li> 
  19.                 <li><label for="file_2">Fichier 2</label></li> 
  20.             </ul> 
  21.         </li> 
  22.     </ul> 
  23.  
  24.     <fieldset> 
  25.         <legend>Informations personnelles</legend> 
  26.         <input type="text" name="first_name" id="first_name" /><br /> 
  27.         <input type="text" name="last_name" id="last_name" /><br /> 
  28.     </fieldset> 
  29.     <fieldset> 
  30.         <legend>Informations virtuelles</legend> 
  31.         <input type="text" name="nickname" id="nickname" /><br /> 
  32.         <input type="text" name="website" id="website" /><br /> 
  33.         <input type="text" name="instant_messenger" id="instant_messenger" /><br /> 
  34.     </fieldset> 
  35.     <fieldset> 
  36.         <legend>Fichiers joints</legend> 
  37.         <input type="file" name="file_1" id="file_1" /><br /> 
  38.         <input type="file" name="file_2" id="file_2" /> 
  39.     </fieldset><br /> 
  40.  
  41.     <input type="submit" value="Envoyer" /> 
  42.     <input type="reset" value="Rétablir" /> 
  43. </form> 

II-B. Partie PHP : traitement du formulaire


Les superglobales $_GET, $_POST et $_FILES

Les informations envoyées au moyen d'un formulaire sont stockées dans les tableaux superglobaux de l'environnement PHP.

Voici les tableaux utilisés :
  • $_GET : Les variables de l'URL (méthode GET)
  • $_POST : Les variables envoyées par la méthode POST
  • $_FILES : Les fichiers envoyés par formulaire
  • $_REQUEST : Les variables $_POST, $_GET et $_COOKIE confondues en une seule (cette superglobale $_REQUEST est à éviter) ; $_FILES n'est plus inclus depuis la version 4.3 de PHP
Il est possible d'utiliser print_r() pour afficher le contenu d'un formulaire :
Afficher le contenu d'un formulaire : form.php
  1. <?php 
  2.  
  3. if(!empty($_POST)) 
  4. { 
  5.     // 
  6.     // Debug 
  7.     // 
  8.     echo '<b>Variables</b> :<br />'; 
  9.     echo '<pre>'; 
  10.     print_r($_POST); 
  11.     echo '</pre>'; 
  12. } 
  13.  
  14. if(!empty($_FILES)) 
  15. { 
  16.     // 
  17.     // Debug 
  18.     // 
  19.     echo '<b>Fichiers</b> :<br />'; 
  20.     echo '<pre>'; 
  21.     print_r($_FILES); 
  22.     echo '</pre>'; 
  23. } 
  24.  
  25. ?> 
  26.  
  27.  
  28. <form method="post" action="form.php" enctype="multipart/form-data"> 
  29.     <label>Titre : <input type="text" name="title" /></label><br /> 
  30.     <label>Message : <br /> 
  31.     <textarea name="message" cols="20" rows="7"></textarea></label><br /> 
  32.     <label>Fichier joint : <input type="file" name="file" /></label><br /><br /> 
  33.  
  34.     <input type="submit" value="Envoyer" /> 
  35.     <input type="reset" value="Rétablir" /> 
  36. </form> 
info Tout au long de ce tutoriel, j'effectuerai mes traitements dans une condition protégée par !empty(). C'est une bonne habitude à prendre, afin de n'effectuer les traitements que dans le cas où le formulaire a été transmis. Si vous ne le faites pas, il est probable que PHP vous affiche des avertissements "undefined index" lorsque le formulaire n'a pas encore été envoyé. Protéger par isset() n'est pas suffisant.
warning Le code ci-dessus et la plupart des exemples suivants sont vulnérables à une faille XSS. Pensez à toujours protéger l'affichage à l'aide de la fonction htmlentities() ou au moins htmlspecialchars().

Les variables

Afin de parcourir le contenu d'un formulaire, il est nécessaire de manipuler le tableau $_POST comme un tableau associatif. Cela signifie que chaque nom de champ (propriété name de chaque contrôle) du formulaire est utilisé comme index de $_POST. Dans l'exemple suivant, deux contrôlent portent un nom : "login" devient $_POST['login'] et "password" devient $_POST['password'].
Exemple de formulaire simple et affichage du contenu : form.php
  1. <?php 
  2.  
  3. if(!empty($_POST)) 
  4. { 
  5.     // 
  6.     // Debug 
  7.     // 
  8.     echo '<pre>'; 
  9.     print_r($_POST); 
  10.     echo '</pre><br />'; 
  11.  
  12.     // 
  13.     // Récupération normale des informations 
  14.     // 
  15.     echo "<b>Nom d'utilisateur</b> : ".$_POST['login'].'<br />'; 
  16.     echo "<b>Mot de passe</b> : ".$_POST['password'].'<br /><br />'; 
  17. } 
  18.  
  19. ?> 
  20.  
  21.  
  22. <form method="post" action="form.php"> 
  23.     <label>Nom d utilisateur : <input type="text" name="login" /></label><br /> 
  24.     <label>Mot de passe : <input type="password" name="password" /></label><br /><br /> 
  25.  
  26.     <input type="submit" value="Envoyer" /> 
  27.     <input type="reset" value="Rétablir" /> 
  28. </form> 

Pour les grands formulaires, il est parfois moins pénible d'utiliser la structure foreach. Tout dépend de l'utilisation du formulaire. N'adaptez surtout pas les noms des contrôles de manière à les afficher directement, car ce serait prendre le problème à l'envers !
Exemple INCORRECT
  1. <?php 
  2.  
  3. if(!empty($_POST)) 
  4. { 
  5.     // 
  6.     // Debug 
  7.     // 
  8.     echo '<pre>'; 
  9.     print_r($_POST); 
  10.     echo '</pre><br />'; 
  11.  
  12.     // 
  13.     // Récupération normale des informations 
  14.     // 
  15.     foreach($_POST as $field => $value) 
  16.     { 
  17.         echo '<b>'.$field.'</b> : '.$value.'<br />'; 
  18.     } 
  19.     echo '<br /><br />'; 
  20. } 
  21.  
  22. ?> 
  23.  
  24.  
  25. <form method="post" action="form.php"> 
  26.     <label>Nom d utilisateur : <input type="text" name="Nom d utilisateur" /></label><br /> 
  27.     <label>Mot de passe : <input type="password" name="Mot de passe" /></label><br /><br /> 
  28.  
  29.     <input type="submit" value="Envoyer" /> 
  30.     <input type="reset" value="Rétablir" /> 
  31. </form> 
Exemple correct de parcours du résultat d'un formulaire : form.php
  1. <?php 
  2.  
  3. if(!empty($_POST)) 
  4. { 
  5.     // 
  6.     // Debug 
  7.     // 
  8.     echo '<pre>'; 
  9.     print_r($_POST); 
  10.     echo '</pre><br />'; 
  11.  
  12.     // 
  13.     // Récupération normale des informations 
  14.     // 
  15.     foreach($_POST as $field => $value) 
  16.     { 
  17.         echo '<b>'.$field.'</b> : '.$value.'<br />'; 
  18.     } 
  19.     echo '<br /><br />'; 
  20. } 
  21.  
  22. ?> 
  23.  
  24.  
  25. <form method="post" action="form.php"> 
  26.     <label>Nom d utilisateur : <input type="text" name="login" /></label><br /> 
  27.     <label>Mot de passe : <input type="password" name="password" /></label><br /><br /> 
  28.  
  29.     <input type="submit" value="Envoyer" /> 
  30.     <input type="reset" value="Rétablir" /> 
  31. </form> 
 

Valid XHTML 1.1!Valid CSS!

Copyright © 2006 Guillaume Rossolini. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.