Les formulaires et PHP5

Image non disponible


précédentsommairesuivant

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'internaute sur notre page : ses informations de connexion (nom d'utilisateur et mot de passe) et comment il nous a connus.

Code 3.1 : forms/1-connection-data.php
Sélectionnez
<form method="post" action="<?php echo CFG_FORM_ACTION; ?>?stage=<?php echo CFG_STAGE_ID+1; ?>">
    <fieldset>
        <legend>Informations de connexion</legend>
        <label>
            Adresse e-mail :
            <input type="text" name="e-mail" value="<?php echo $_SESSION['forms'][CFG_STAGE_ID]['e-mail']; ?>" />
        </label><br />
        <label>
            Mot de passe :
            <input type="password" name="password-1" />
        </label><br />
        <label>
            Mot de passe (répéter) :
            <input type="password" name="password-2" />
        </label>
    </fieldset><br />
 
    <fieldset>
        <legend>Autres informations</legend>
        <label>
            Comment nous avez-vous connus ?
            <select name="referer">
                <option value="friend"<?php
                    if($_SESSION['forms'][CFG_STAGE_ID]['referer'] == 'friend'){echo ' selected="selected"';}
                    ?>>Par un ami</option>
                <option value="search-engine"<?php
                    if($_SESSION['forms'][CFG_STAGE_ID]['referer'] == 'search-engine'){echo ' selected="selected"';}
                    ?>>Par un moteur de recherche</option>
                <option value="press"<?php
                    if($_SESSION['forms'][CFG_STAGE_ID]['referer'] == 'press'){echo ' selected="selected"';}
                    ?>>Par la presse</option>
                <option value="other"<?php
                    if($_SESSION['forms'][CFG_STAGE_ID]['referer'] == 'other'){echo ' selected="selected"';}
                    ?>>Autre</option>
            </select>
        </label><br />
        <label>
            Pouvez-vous préciser ?
            <input type="text" name="details" value="<?php echo $_SESSION['forms'][CFG_STAGE_ID]['details']; ?>" />
        </label>
    </fieldset>
 
    <input type="submit" value="Envoyer et continuer" />
</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.

Code 3.2 : forms/2-personal-data.php
Sélectionnez
<form method="post" action="<?php echo CFG_FORM_ACTION; ?>?stage=<?php echo CFG_STAGE_ID+1; ?>">
    <fieldset>
        <legend>Informations personnelles</legend>
        <label>
            Prénom :
            <input type="text" name="first-name" value="<?php
                echo $_SESSION['forms'][CFG_STAGE_ID]['first-name'];
                ?>" />
        </label><br />
        <label>
            Nom :
            <input type="text" name="last-name" value="<?php
                echo $_SESSION['forms'][CFG_STAGE_ID]['last-name'];
                ?>" />
        </label><br />
        <label>
            Ville :
            <input type="text" name="city" value="<?php
                echo $_SESSION['forms'][CFG_STAGE_ID]['city'];
                ?>" />
        </label><br />
        <label>
            Code postal :
            <input type="text" name="postal-code" value="<?php
                echo $_SESSION['forms'][CFG_STAGE_ID]['postal-code'];
                ?>" />
        </label><br />
    </fieldset>
 
    <input type="submit" value="Envoyer et continuer" />
</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.

Code 3.3 : forms/3-studies.php
Sélectionnez
<form method="post" action="<?php echo CFG_FORM_ACTION; ?>?stage=<?php echo CFG_STAGE_ID+1; ?>">
    <fieldset>
        <legend>Informations personnelles</legend>
        <label>
            Études :<br />
            <textarea name="studies" cols="15" rows="10"><?php
                echo $_SESSION['forms'][CFG_STAGE_ID]['studies'];
                ?></textarea>
        </label>
    </fieldset>
 
    <input type="submit" value="Envoyer et continuer" />
</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.

Code 3.4 : forms/4-summary.php
Sélectionnez
<?php
 
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
 
?>

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.

Code 3.5
Sélectionnez
session_start();
 
// Configuration du script
define('CFG_FORM_ACTION', basename(__FILE__)); // Cela permet de changer le nom du script d'index
$forms = array( // Voici la liste des formulaires, pratique pour mettre en place le menu de navigation
    1 => 'Informations de connexion',
    2 => 'Informations personnelles',
    3 => 'Études'
    );
 
// Récupération du numéro de l'étape en cours
if(empty($_GET['stage']) or !is_numeric($_GET['stage']))
{
    define('CFG_STAGE_ID', 1);
}
else
{
    // En situation réelle, il faudrait vérifier l'existence de cette page
    define('CFG_STAGE_ID', intval($_GET['stage']));
}
 
// Déclaration de la variable de session
if(empty($_SESSION['forms']))
{
    $_SESSION['forms'] = array();
}

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.

Code 3.6
Sélectionnez
// Affichage du menu en haut de la page
$items = array();
foreach($forms as $form_id => $form_name)
{
    if(empty($_SESSION['forms'][$form_id]))
    {
        $items[] = $form_name;
    }
    else
    {
        $items[] = '<a href="'.basename(__FILE__).'?stage='.$form_id.'">'.$form_name.'</a>';
    }
}
$items[] = '<a href="'.basename(__FILE__).'?stage=4">Résumé</a>';
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.

Code 3.7 : Le squelette
Sélectionnez
// Récupération des informations, affichage du formulaire
switch(CFG_STAGE_ID)
{
    case 4:
        // Récupération des informations du formulaire précédent
        if(!empty($_POST))
        {
            // Vérification des champs puis affectation à la variable de session
        }
 
        // Inclusion de la page de résumé
    break;
 
 
    case 3:
        // Valeurs par défaut
        if(empty($_SESSION['forms'][CFG_STAGE_ID]))
        {
            $_SESSION['forms'][CFG_STAGE_ID] = ...
        }
 
        // Récupération des informations du formulaire précédent
        if(!empty($_POST))
        {
            // Vérification des champs puis affectation à la variable de session
        }
 
        // Inclusion du formulaire adéquat
    break;
 
    case 2:
        // Valeurs par défaut
        if(empty($_SESSION['forms'][CFG_STAGE_ID]))
        {
            $_SESSION['forms'][CFG_STAGE_ID] = ...
        }
 
        // Récupération des informations du formulaire précédent
        if(!empty($_POST))
        {
            // Vérification des champs puis affectation à la variable de session
        }
 
        // Inclusion du formulaire adéquat
    break;
 
    case 1:
    default:
        // Valeurs par défaut
        if(empty($_SESSION['forms'][CFG_STAGE_ID]))
        {
            $_SESSION['forms'][CFG_STAGE_ID] = ...
        }
 
        // Inclusion du formulaire adéquat
    break;
}

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.

Code 3.8 : Le script
Sélectionnez
// Récupération des informations, affichage du formulaire
switch(CFG_STAGE_ID)
{
    case 4:
        // Récupération des informations du formulaire précédent
        if(!empty($_POST))
        {
            if(!empty($_POST['studies']))
            {
                $_SESSION['forms'][CFG_STAGE_ID-1] = array(
                    'studies'   => $_POST['studies']
                    );
            }
        }
 
        // Affichage du formulaire
        require('./forms/4-summary.php');
    break;
 
 
    case 3:
        // Valeurs par défaut
        if(empty($_SESSION['forms'][CFG_STAGE_ID]))
        {
            $_SESSION['forms'][CFG_STAGE_ID] = array(
                'studies'   => ''
                );
        }
 
        // Récupération des informations du formulaire précédent
        if(!empty($_POST))
        {
            if(!empty($_POST['last-name'])
                and !empty($_POST['first-name'])
                and !empty($_POST['city'])
                and !empty($_POST['postal-code'])
                and is_numeric($_POST['postal-code']))
            {
                $_SESSION['forms'][CFG_STAGE_ID-1] = array(
                    'first-name'  => $_POST['first-name'],
                    'last-name'   => $_POST['last-name'],
                    'city'  => $_POST['city'],
                    'postal-code' => $_POST['postal-code']
                    );
            }
        }
 
        // Affichage du formulaire
        require('./forms/3-studies.php');
    break;
 
    case 2:
        // Valeurs par défaut
        if(empty($_SESSION['forms'][CFG_STAGE_ID]))
        {
            $_SESSION['forms'][CFG_STAGE_ID] = array(
                'first-name'  => '',
                'last-name'   => '',
                'city'  => '',
                'postal-code' => NULL
                );
        }
 
        // Récupération des informations du formulaire précédent
        if(!empty($_POST))
        {
            if(!empty($_POST['e-mail'])
                and !empty($_POST['password-1'])
                and !empty($_POST['password-2'])
                and preg_match('/^([^@\s<&>]+)@(?:([-a-z0-9]+)\.)+([a-z]{2,})$/i', $_POST['e-mail'])
                and $_POST['password-1'] == $_POST['password-2'])
            {
                $_SESSION['forms'][CFG_STAGE_ID-1] = array(
                    'e-mail'   => $_POST['e-mail'],
                    'password' => md5($_POST['password-1']),
                    'referer'  => $_POST['referer'],
                    'details'  => $_POST['details']
                    );
            }
        }
 
        require('./forms/2-personal-data.php');
    break;
 
    case 1:
    default:
        // Valeurs par défaut
        if(empty($_SESSION['forms'][CFG_STAGE_ID]))
        {
            $_SESSION['forms'][CFG_STAGE_ID] = array(
                'e-mail'   => '',
                'password' => '',
                'referer'  => 'friend',
                'details'  => ''
                );
        }
 
        require('./forms/1-connection-data.php');
    break;
}

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.

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.

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.


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2006 Guillaume Rossolini. Aucune reproduction, même partielle, ne peut être faite de ce site et 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.