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


IV. Formulaire réparti sur plusieurs pages
IV-A. Les formulaires
Informations de connexion
Informations personnelles
Études
Résumé
IV-B. La page d'index
Mise en place des variables
Les liens en haut de la page
Traitement des données utilisateur
IV-C. Fonctionnement
IV-C-1. Mise en place
IV-C-2. Navigation
IV-C-3. Sécurité


IV. Formulaire réparti sur plusieurs pages

L'un des thèmes récurrents de nos forums est "j'ai un formulaire sur plusieurs pages, comment faire pour..." : après avoir lu ce tutoriel jusqu'ici, vous devriez savoir que la majorité des formulaires peuvent être présentés en une seule page (notamment à l'aide de la balise >fieldset<)..
Cependant, certaines situations nécessitent un formulaire tellement long qu'il est préférable de le découper en plusieurs étapes, chacune étant située sur sa propre page. Nous allons voir ici plusieurs méthodes pour y parvenir.

Prenons un exemple concret : un site de recherche d'emploi. Chaque postulant doit renseigner plusieurs dizaines d'informations, ce qui rendrait le tout impossible à gérer si nous ne proposions qu'un unique formulaire. Il est préférable d'y aller par étapes.

Voici ce sur quoi nous allons nous fonder :
  1. Informations de connexion
  2. Informations personnelles
  3. Études
  4. Expérience
  5. Connaissances
  6. Alertes
Je vous propose d'utiliser un fichier d'index et plusieurs fichiers à inclure. Cela permet d'avoir nos formulaires HTML dans des fichiers séparés du code PHP. Pour les connaisseurs, cette méthode est très similaire à l'utilisation d'un moteur de gabarits et vous n'aurez aucun mal à l'adapter.

Arborescence du site :
  • /index.php
  • /forms/1-connection-data.php
  • /forms/2-personal-data.php
  • /forms/3-studies.php
  • /forms/4-summary.php

IV-A. Les formulaires

Mon objectif ici n'est pas de construire un site de recherche d'emploi, je ne vais donc pas étudier toutes les étapes en détail. Les trois premières suffiront et je ne vais proposer ici que des formulaires simples.


Informations de connexion

Ce premier formulaire concerne l'arrivée de l'iternaute sur notre page : ses informations de connexion (nom d'utilisateur et mot de passe) et comment il nous a connus.
forms/1-connection-data.php
  1. <form method="post" action="<?php echo CFG_FORM_ACTION; ?>?stage=<?php echo CFG_STAGE_ID+1; ?>"> 
  2.     <fieldset> 
  3.         <legend>Informations de connexion</legend> 
  4.         <label> 
  5.             Adresse e-mail : 
  6.             <input type="text" name="e-mail" value="<?php echo $_SESSION['forms'][CFG_STAGE_ID]['e-mail']; ?>" /> 
  7.         </label><br /> 
  8.         <label> 
  9.             Mot de passe : 
  10.             <input type="password" name="password-1" /> 
  11.         </label><br /> 
  12.         <label> 
  13.             Mot de passe (répéter) : 
  14.             <input type="password" name="password-2" /> 
  15.         </label> 
  16.     </fieldset><br /> 
  17.  
  18.     <fieldset> 
  19.         <legend>Autres informations</legend> 
  20.         <label> 
  21.             Comment nous avez-vous connus ? 
  22.             <select name="referer"> 
  23.                 <option value="friend"<?php 
  24.                     if($_SESSION['forms'][CFG_STAGE_ID]['referer'] == 'friend'){echo ' selected="selected"';} 
  25.                     ?>>Par un ami</option> 
  26.                 <option value="search-engine"<?php 
  27.                     if($_SESSION['forms'][CFG_STAGE_ID]['referer'] == 'search-engine'){echo ' selected="selected"';} 
  28.                     ?>>Par un moteur de recherche</option> 
  29.                 <option value="press"<?php 
  30.                     if($_SESSION['forms'][CFG_STAGE_ID]['referer'] == 'press'){echo ' selected="selected"';} 
  31.                     ?>>Par la presse</option> 
  32.                 <option value="other"<?php 
  33.                     if($_SESSION['forms'][CFG_STAGE_ID]['referer'] == 'other'){echo ' selected="selected"';} 
  34.                     ?>>Autre</option> 
  35.             </select> 
  36.         </label><br /> 
  37.         <label> 
  38.             Pouvez-vous préciser ? 
  39.             <input type="text" name="details" value="<?php echo $_SESSION['forms'][CFG_STAGE_ID]['details']; ?>" /> 
  40.         </label> 
  41.     </fieldset> 
  42.  
  43.     <input type="submit" value="Envoyer et continuer" /> 
  44. </form> 

Informations personnelles

C'est ici qu'il faut demander toutes les informations civiles à notre internaute. En situation réelle, il faudrait étoffer cette liste.
forms/2-personal-data.php
  1. <form method="post" action="<?php echo CFG_FORM_ACTION; ?>?stage=<?php echo CFG_STAGE_ID+1; ?>"> 
  2.     <fieldset> 
  3.         <legend>Informations personnelles</legend> 
  4.         <label> 
  5.             Prénom : 
  6.             <input type="text" name="first-name" value="<?php 
  7.                 echo $_SESSION['forms'][CFG_STAGE_ID]['first-name']; 
  8.                 ?>" /> 
  9.         </label><br /> 
  10.         <label> 
  11.             Nom : 
  12.             <input type="text" name="last-name" value="<?php 
  13.                 echo $_SESSION['forms'][CFG_STAGE_ID]['last-name']; 
  14.                 ?>" /> 
  15.         </label><br /> 
  16.         <label> 
  17.             Ville : 
  18.             <input type="text" name="city" value="<?php 
  19.                 echo $_SESSION['forms'][CFG_STAGE_ID]['city']; 
  20.                 ?>" /> 
  21.         </label><br /> 
  22.         <label> 
  23.             Code postal : 
  24.             <input type="text" name="postal-code" value="<?php 
  25.                 echo $_SESSION['forms'][CFG_STAGE_ID]['postal-code']; 
  26.                 ?>" /> 
  27.         </label><br /> 
  28.     </fieldset> 
  29.  
  30.     <input type="submit" value="Envoyer et continuer" /> 
  31. </form> 

Études

Comme ce tutoriel n'est qu'un exemple d'un formulaire réparti sur plusieurs pages, j'ai simplifié ce formulaire à un simple contrôle <textarea>. Dans une situation réelle, il faudrait un formulaire bien plus flexible que cela.
forms/3-studies.php
  1. <form method="post" action="<?php echo CFG_FORM_ACTION; ?>?stage=<?php echo CFG_STAGE_ID+1; ?>"> 
  2.     <fieldset> 
  3.         <legend>Informations personnelles</legend> 
  4.         <label> 
  5.             Études :<br /> 
  6.             <textarea name="studies" cols="15" rows="10"><?php 
  7.                 echo $_SESSION['forms'][CFG_STAGE_ID]['studies']; 
  8.                 ?></textarea> 
  9.         </label> 
  10.     </fieldset> 
  11.  
  12.     <input type="submit" value="Envoyer et continuer" /> 
  13. </form> 

Résumé

Je me contente ici d'afficher des informations de débogage, mais il est évident qu'en situation réelle il serait préférable de soigner la présentation.
forms/4-summary.php
  1. <?php 
  2.  
  3. echo '<pre>'; 
  4. print_r($_SESSION); 
  5. echo '</pre>'; 
  6.  
  7. ?> 

IV-B. La page d'index

Les informations de chaque formulaire soumis sont intégralement conservées sur le serveur et nous les réutilisons chaque fois que l'internaute en a besoin. Le plus simple est d'utiliser des sessions, mais le plus flexible est bien sûr d'utiliser une base de données. Quoi qu'il en soit, la session est nécessaire pour passer les informations d'un formulaire à l'autre.

Pour simplifier les exemples, je vais me contenter d'une session PHP sans base de données.


Mise en place des variables

Le début de notre script d'index doit mettre en place l'environnement : la session et les variables de configuration.
  1. session_start(); 
  2.  
  3. // Configuration du script 
  4. define('CFG_FORM_ACTION', basename(__FILE__)); // Cela permet de changer le nom du script d'index 
  5. $forms = array 
  6. ( // Voici la liste des formulaires, pratique pour mettre en place le menu de navigation 
  7.     1 => 'Informations de connexion', 
  8.     2 => 'Informations personnelles', 
  9.     3 => 'Études' 
  10. ); 
  11.  
  12. // Récupération du numéro de l'étape en cours 
  13. if(empty($_GET['stage']) or !is_numeric($_GET['stage'])) 
  14. { 
  15.     define('CFG_STAGE_ID', 1); 
  16. } 
  17. else 
  18. { 
  19.     // En situation réelle, il faudrait vérifier l'existence de cette page 
  20.     define('CFG_STAGE_ID', intval($_GET['stage'])); 
  21. } 
  22.  
  23. // Déclaration de la variable de session 
  24. if(empty($_SESSION['forms'])) 
  25. { 
  26.     $_SESSION['forms'] = array(); 
  27. } 

Les liens en haut de la page

Il est toujours intéressant de proposer un menu de navigation à notre utilisateur. Ici, cela lui évitera probablement d'utiliser les boutons de navigation de son navigateur, tellement agaçants par moments.

Les pages qui n'ont pas encore été visitées ne comportent pas de lien, afin d'éviter à l'utilisateur de sauter des étapes. Dans une situation réelle, il faudrait vérifier que l'utilisateur n'a pas modifié le paramètre de l'URI à la main.
  1. // Affichage du menu en haut de la page 
  2. $items = array(); 
  3. foreach($forms as $form_id => $form_name) 
  4. { 
  5.     if(empty($_SESSION['forms'][$form_id])) 
  6.     { 
  7.         $items[] = $form_name; 
  8.     } 
  9.     else 
  10.     { 
  11.         $items[] = '<a href="'.basename(__FILE__).'?stage='.$form_id.'">'.$form_name.'</a>'; 
  12.     } 
  13. } 
  14. $items[] = '<a href="'.basename(__FILE__).'?stage=4">Résumé</a>'; 
  15. echo implode(' - ', $items).'<br /><br />'; 

Traitement des données utilisateur

Enfin, il nous faut traiter les données envoyées par notre internaute, c'est-à-dire qu'il faut les envoyer dans notre variable de session (ou dans la base de données, le cas échéant).

Puisque ce script est un peu long, je vous propose d'abord son squelette pour vous permettre de vous familiariser avec son fonctionnement.
Le squelette :
  1. // Récupération des informations, affichage du formulaire 
  2. switch(CFG_STAGE_ID) 
  3. { 
  4.     case 4: 
  5.         // Récupération des informations du formulaire précédent 
  6.         if(!empty($_POST)) 
  7.         { 
  8.             // Vérification des champs puis affectation à la variable de session 
  9.         } 
  10.  
  11.         // Inclusion de la page de résumé 
  12.     break; 
  13.  
  14.  
  15.     case 3: 
  16.         // Valeurs par défaut 
  17.         if(empty($_SESSION['forms'][CFG_STAGE_ID])) 
  18.         { 
  19.             $_SESSION['forms'][CFG_STAGE_ID] = ... 
  20.         } 
  21.  
  22.         // Récupération des informations du formulaire précédent 
  23.         if(!empty($_POST)) 
  24.         { 
  25.             // Vérification des champs puis affectation à la variable de session 
  26.         } 
  27.  
  28.         // Inclusion du formulaire adéquat 
  29.     break; 
  30.  
  31.     case 2: 
  32.         // Valeurs par défaut 
  33.         if(empty($_SESSION['forms'][CFG_STAGE_ID])) 
  34.         { 
  35.             $_SESSION['forms'][CFG_STAGE_ID] = ... 
  36.         } 
  37.  
  38.         // Récupération des informations du formulaire précédent 
  39.         if(!empty($_POST)) 
  40.         { 
  41.             // Vérification des champs puis affectation à la variable de session 
  42.         } 
  43.  
  44.         // Inclusion du formulaire adéquat 
  45.     break; 
  46.  
  47.     case 1: 
  48.     default: 
  49.         // Valeurs par défaut 
  50.         if(empty($_SESSION['forms'][CFG_STAGE_ID])) 
  51.         { 
  52.             $_SESSION['forms'][CFG_STAGE_ID] = ... 
  53.         } 
  54.  
  55.         // Inclusion du formulaire adéquat 
  56.     break; 
  57. } 

La structure de ce script me semble suffisament claire pour parler d'elle-même : selon l'étape en cours, nous effectuons un traitement ou un autre. Voyons maintenant le script réel.
Le script :
  1. // Récupération des informations, affichage du formulaire 
  2. switch(CFG_STAGE_ID) 
  3. { 
  4.     case 4: 
  5.         // Récupération des informations du formulaire précédent 
  6.         if(!empty($_POST)) 
  7.         { 
  8.             if(!empty($_POST['studies'])) 
  9.             { 
  10.                 $_SESSION['forms'][CFG_STAGE_ID-1] = array( 
  11.                     'studies'   => $_POST['studies'] 
  12.                     ); 
  13.             } 
  14.         } 
  15.  
  16.         // Affichage du formulaire 
  17.         require('./forms/4-summary.php'); 
  18.     break; 
  19.  
  20.  
  21.     case 3: 
  22.         // Valeurs par défaut 
  23.         if(empty($_SESSION['forms'][CFG_STAGE_ID])) 
  24.         { 
  25.             $_SESSION['forms'][CFG_STAGE_ID] = array( 
  26.                 'studies'   => '' 
  27.                 ); 
  28.         } 
  29.  
  30.         // Récupération des informations du formulaire précédent 
  31.         if(!empty($_POST)) 
  32.         { 
  33.             if(!empty($_POST['last-name']) 
  34.                 and !empty($_POST['first-name']) 
  35.                 and !empty($_POST['city']) 
  36.                 and !empty($_POST['postal-code']) 
  37.                 and is_numeric($_POST['postal-code'])) 
  38.             { 
  39.                 $_SESSION['forms'][CFG_STAGE_ID-1] = array( 
  40.                     'first-name'  => $_POST['first-name'], 
  41.                     'last-name'   => $_POST['last-name'], 
  42.                     'city'  => $_POST['city'], 
  43.                     'postal-code' => $_POST['postal-code'] 
  44.                     ); 
  45.             } 
  46.         } 
  47.  
  48.         // Affichage du formulaire 
  49.         require('./forms/3-studies.php'); 
  50.     break; 
  51.  
  52.     case 2: 
  53.         // Valeurs par défaut 
  54.         if(empty($_SESSION['forms'][CFG_STAGE_ID])) 
  55.         { 
  56.             $_SESSION['forms'][CFG_STAGE_ID] = array( 
  57.                 'first-name'  => '', 
  58.                 'last-name'   => '', 
  59.                 'city'  => '', 
  60.                 'postal-code' => NULL 
  61.                 ); 
  62.         } 
  63.  
  64.         // Récupération des informations du formulaire précédent 
  65.         if(!empty($_POST)) 
  66.         { 
  67.             if(!empty($_POST['e-mail']) 
  68.                 and !empty($_POST['password-1']) 
  69.                 and !empty($_POST['password-2']) 
  70.                 and preg_match('/^([^@\s<&>]+)@(?:([-a-z0-9]+)\.)+([a-z]{2,})$/i', $_POST['e-mail']) 
  71.                 and $_POST['password-1'] == $_POST['password-2']) 
  72.             { 
  73.                 $_SESSION['forms'][CFG_STAGE_ID-1] = array( 
  74.                     'e-mail'   => $_POST['e-mail'], 
  75.                     'password' => md5($_POST['password-1']), 
  76.                     'referer'  => $_POST['referer'], 
  77.                     'details'  => $_POST['details'] 
  78.                     ); 
  79.             } 
  80.         } 
  81.  
  82.         require('./forms/2-personal-data.php'); 
  83.     break; 
  84.  
  85.     case 1: 
  86.     default: 
  87.         // Valeurs par défaut 
  88.         if(empty($_SESSION['forms'][CFG_STAGE_ID])) 
  89.         { 
  90.             $_SESSION['forms'][CFG_STAGE_ID] = array( 
  91.                 'e-mail'   => '', 
  92.                 'password' => '', 
  93.                 'referer'  => 'friend', 
  94.                 'details'  => '' 
  95.                 ); 
  96.         } 
  97.  
  98.         require('./forms/1-connection-data.php'); 
  99.     break; 
  100. } 

IV-C. Fonctionnement


IV-C-1. Mise en place

La mise en place de ces formulaires est simple : il suffit de créer l'arborescence évoquée plus haut.

./images/kit-telecharger-code.png Télécharger ces scripts par [ FTP ] ou bien par le miroir [ HTTP ].

IV-C-2. Navigation

Ma foi, la navigation est intuitive... Il faut remplir les formulaires à partir du premier jusqu'au dernier et il est possible de revenir en arrière.

info Testez ces scripts.

IV-C-3. Sécurité

Comme toujours dans ce tutoriel, je n'ai effectué que des contrôles minimalistes. Ce n'est pas le sujet ici mais, en situation réelle, il convient de s'y attarder davantage.

 

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.