Les formulaires et PHP5

Image non disponible


précédentsommairesuivant

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.

Code 1.1 : Formulaire minimum
Sélectionnez
<form method="post" action="form.php">
    <input type="submit" value="Envoyer" />
</form>

http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/1-1.php

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.

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
Code 1.2 : Formulaire mixte
Sélectionnez
<form method="POST" action="test.php" enctype="multipart/form-data">
    Une ligne de texte (quelques mots) :
    <input type="text" name="text" /><br />
 
    Un mot de passe :
    <input type="password" name="password" /><br />
 
    Case à cocher :
    <input type="checkbox" name="checkbox_1" checked="checked" />
    <input type="checkbox" name="checkbox_2" />
    <input type="checkbox" name="checkbox_3" /><br />
 
    Bouton radio à sélectionner :
    <input type="radio" name="radio" checked="checked" />
    <input type="radio" name="radio" />
    <input type="radio" name="radio" /><br />
 
    Envoy de fichier :
    <input type="file" name="file" /><br />
 
    Bloc de texte (plusieurs lignes) :
    <textarea name="textarea" cols="20" rows="7"></textarea><br />
 
    Liste de valeurs :
    <select name="select">
        <option value="Option 1">Option 1</option>
        <option value="Option 2">Option 2</option>
        <option value="Option 3">Option 3</option>
    </select><br />
 
    Champ caché :
    <input type="hidden" name="hidden" /><br />
 
    Image servant de bouton :
    <input type="image" src="http://www.developpez.net/forums/images/logo16.gif" /><br />
 
    Bouton minimal :
    <input type="button" value="Bouton inutile" /><br />
 
    Bouton d'envoi :
    <input type="submit" value="Envoyer" /><br />
 
    Bouton de réinitialisation :
    <input type="reset" value="Rétablir" />
</form>

http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/1-2.php

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 en utilisant la touche "Entrée", 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.

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="".

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).

Code 1.3 : Exemple de fieldset+legend
Sélectionnez
<form method="post" action="form.php">
    <fieldset>
        <legend>Informations personnelles</legend>
        Prénom : <input type="text" name="first_name" /><br />
        Nom : <input type="text" name="last_name" /><br />
    </fieldset>
    <fieldset>
        <legend>Informations virtuelles</legend>
        Pseudonyme : <input type="text" name="nickname" /><br />
        Site Web : <input type="text" name="website" /><br />
        Messagerie instantanée : <input type="text" name="instant_messenger" /><br />
    </fieldset><br />
 
    <input type="submit" value="Envoyer" />
    <input type="reset" value="Rétablir" />
</form>

http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/1-3.php

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 :

Code 1.4 : Exemple de label
Sélectionnez
<form method="post" action="form.php">
    <fieldset>
        <legend>Informations personnelles</legend>
        <label>
            Prénom : <input type="text" name="first_name" />
        </label><br />
        <label>
            Nom : <input type="text" name="last_name" />
        </label><br />
    </fieldset>
    <fieldset>
        <legend>Informations virtuelles</legend>
        <label>
            Pseudonyme : <input type="text" name="nickname" />
        </label><br />
        <label>
            Site Web : <input type="text" name="website" />
        </label><br />
        <label>
            Messagerie instantanée : <input type="text" name="instant_messenger" />
        </label><br />
    </fieldset>
    <fieldset>
        <legend>Fichiers joints</legend>
        <label>
            Fichier 1 : <input type="file" name="file_1" />
        </label><br />
        <label>
            Fichier 2 : <input type="file" name="file_2" />
        </label><br />
    </fieldset><br />
 
    <input type="submit" value="Envoyer" />
    <input type="reset" value="Rétablir" />
</form>

http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/1-4.php

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é.

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.

Code 1.5 : Exemple d'association explicite
Sélectionnez
<form method="post" action="form.php">
    <ul>
        <li>Informations personnelles
            <ul>
                <li><label for="first_name">Prénom</label></li>
                <li><label for="last_name">Nom</label></li>
            </ul>
        </li>
        <li>Informations virtuelles
            <ul>
                <li><label for="nickname">Pseudonyme</label></li>
                <li><label for="website">Site Web</label></li>
                <li><label for="instant_messenger">Messagerie instantanée</label></li>
            </ul>
        </li>
        <li>Fichiers joints
            <ul>
                <li><label for="file_1">Fichier 1</label></li>
                <li><label for="file_2">Fichier 2</label></li>
            </ul>
        </li>
    </ul>
 
    <fieldset>
        <legend>Informations personnelles</legend>
        <input type="text" name="first_name" id="first_name" /><br />
        <input type="text" name="last_name" id="last_name" /><br />
    </fieldset>
    <fieldset>
        <legend>Informations virtuelles</legend>
        <input type="text" name="nickname" id="nickname" /><br />
        <input type="text" name="website" id="website" /><br />
        <input type="text" name="instant_messenger" id="instant_messenger" /><br />
    </fieldset>
    <fieldset>
        <legend>Fichiers joints</legend>
        <input type="file" name="file_1" id="file_1" /><br />
        <input type="file" name="file_2" id="file_2" />
    </fieldset><br />
 
    <input type="submit" value="Envoyer" />
    <input type="reset" value="Rétablir" />
</form>

http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/1-5.php

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 :

Code 1.6 : Afficher le contenu d'un formulaire
Sélectionnez
<?php
 
if(!empty($_POST)){
    //
    // Debug
    //
    echo '<b>Variables</b> :<br />';
    echo '<pre>';
    print_r($_POST);
    echo '</pre>';
}
 
if(!empty($_FILES)){
    //
    // Debug
    //
    echo '<b>Fichiers</b> :<br />';
    echo '<pre>';
    print_r($_FILES);
    echo '</pre>';
}
 
?>
 
 
<form method="post" action="form.php" enctype="multipart/form-data">
    <label>Titre : <input type="text" name="title" /></label><br />
    <label>Message : <br />
    <textarea name="message" cols="20" rows="7"></textarea></label><br />
    <label>Fichier joint : <input type="file" name="file" /></label><br /><br />
 
    <input type="submit" value="Envoyer" />
    <input type="reset" value="Rétablir" />
</form>

http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/1-6.php

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.

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ôles portent un nom : "login" devient $_POST['login'] et "password" devient $_POST['password'].

Code 1.7 : Exemple de formulaire simple et affichage du contenu
Sélectionnez
<?php
 
if(!empty($_POST)){
    //
    // Debug
    //
    echo '<pre>';
    print_r($_POST);
    echo '</pre><br />';
 
    //
    // Récupération normale des informations
    //
    echo "<b>Nom d'utilisateur</b> : ".$_POST['login'].'<br />';
    echo "<b>Mot de passe</b> : ".$_POST['password'].'<br /><br />';
}
 
?>
 
 
<form method="post" action="form.php">
    <label>Nom d utilisateur : <input type="text" name="login" /></label><br />
    <label>Mot de passe : <input type="password" name="password" /></label><br /><br />
 
    <input type="submit" value="Envoyer" />
    <input type="reset" value="Rétablir" />
</form>

http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/1-7.php


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 !

Code 1.8 : Exemple INCORRECT
Sélectionnez
<?php
 
if(!empty($_POST)){
    //
    // Debug
    //
    echo '<pre>';
    print_r($_POST);
    echo '</pre><br />';
 
    //
    // Récupération normale des informations
    //
    foreach($_POST as $field => $value){
        echo '<b>'.$field.'</b> : '.$value.'<br />';
    }
    echo '<br /><br />';
}
 
?>
 
 
<form method="post" action="form.php">
    <label>Nom d utilisateur : <input type="text" name="Nom d utilisateur" /></label><br />
    <label>Mot de passe : <input type="password" name="Mot de passe" /></label><br /><br />
 
    <input type="submit" value="Envoyer" />
    <input type="reset" value="Rétablir" />
</form>

http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/1-8.php

Code 1.9 : Exemple correct de parcours du résultat d'un formulaire
Sélectionnez
<?php
 
if(!empty($_POST)){
    //
    // Debug
    //
    echo '<pre>';
    print_r($_POST);
    echo '</pre><br />';
 
    //
    // Récupération normale des informations
    //
    foreach($_POST as $field => $value){
        echo '<b>'.$field.'</b> : '.$value.'<br />';
    }
    echo '<br /><br />';
}
 
?>
 
 
<form method="post" action="form.php">
    <label>Nom d utilisateur : <input type="text" name="login" /></label><br />
    <label>Mot de passe : <input type="password" name="password" /></label><br /><br />
 
    <input type="submit" value="Envoyer" />
    <input type="reset" value="Rétablir" />
</form>

http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/1-9.php


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.