Yogui PHP Formulaires
Yogui PHP Formulaires
Yogui PHP Formulaires
Comment envoyer des informations à un site Web ? Comment est-il possible de publier une
news sur son site, voire de gérer tout son site (backend) ?
Ce tutoriel traite de différentes manières permettant de récupérer des informations depuis
un formulaire HTML à l'aide d'un script PHP.
Commentez
Les formulaires et PHP5 par Guillaume Rossolini
I - Introduction..............................................................................................................................................................3
I-A - Remerciements.............................................................................................................................................. 3
I-B - Problématique................................................................................................................................................ 3
II - Vision d'ensemble.................................................................................................................................................. 3
II-A - Partie HTML : le formulaire lui-même...........................................................................................................3
Obligatoire : la balise <form>............................................................................................................................3
Fondamental : les contrôles <input>, <textarea>, <select> etc........................................................................4
Facultatif mais pratique : <fieldset>, <legend> et <label>................................................................................5
II-B - Partie PHP : traitement du formulaire...........................................................................................................7
Les superglobales $_GET, $_POST et $_FILES............................................................................................. 7
Les variables..................................................................................................................................................... 8
III - Mise en pratique................................................................................................................................................. 10
III-A - Uniquement du texte : application/x-www-form-urlencoded.......................................................................10
Le contrôle de saisie de texte court : <input type="text" />............................................................................ 11
Le contrôle caché : <input type="hidden" />................................................................................................... 11
Le contrôle de choix alternatifs : <input type="radio" />................................................................................. 12
Le contrôle de choix multiples : <input type="checkbox" />........................................................................... 13
Le contrôle de saisie de texte long : <textarea></textarea>.......................................................................... 14
Le contrôle de choix alternatifs ou multiples : <select></select>................................................................... 15
III-B - Du texte + des fichiers : multipart/form-data..............................................................................................19
Les contrôles classiques.................................................................................................................................20
Le contrôle de choix de fichier : <input type="file" />..................................................................................... 20
Les fonctions PHP.......................................................................................................................................... 26
IV - Formulaire réparti sur plusieurs pages...............................................................................................................27
IV-A - Les formulaires.......................................................................................................................................... 28
Informations de connexion..............................................................................................................................28
Informations personnelles............................................................................................................................... 29
Études..............................................................................................................................................................29
Résumé........................................................................................................................................................... 30
IV-B - La page d'index......................................................................................................................................... 30
Mise en place des variables........................................................................................................................... 30
Les liens en haut de la page..........................................................................................................................31
Traitement des données utilisateur.................................................................................................................31
IV-C - Fonctionnement......................................................................................................................................... 34
IV-C-1 - Mise en place................................................................................................................................... 34
IV-C-2 - Navigation......................................................................................................................................... 34
IV-C-3 - Sécurité............................................................................................................................................. 34
V - Améliorations de l'expérience utilisateur............................................................................................................. 34
V-A - Les boutons "actualiser" et "précédent" du navigateur.............................................................................. 34
La fonction header()........................................................................................................................................34
Bien organiser son code.................................................................................................................................35
V-B - Un peu de JS (JavaScript)......................................................................................................................... 35
Les évènements disponibles...........................................................................................................................35
Vérifier que le formulaire est complètement rempli........................................................................................36
Contrôler que les deux mots de passe sont identiques................................................................................. 38
V-C - Un peu de CSS (feuilles de style)............................................................................................................. 39
VI - Conclusion.......................................................................................................................................................... 41
VI-A - Épilogue..................................................................................................................................................... 41
VI-B - Liens...........................................................................................................................................................41
-2-
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
I - Introduction
I-A - Remerciements
Un grand merci à siddh et titoumimi pour leurs commentaires, ainsi qu'à Maxoo pour m'avoir fourni la feuille de
style utilisée en fin d'article.
I-B - Problématique
Il nous arrive fréquemment de voir des formulaires sur Internet. Ils prennent l'allure d'un sondage, d'une boîte de
connexion ou encore d'une interface permettant de publier un message sur un forum.
Ces formulaires permettent à l'internaute d'envoyer des informations au site Web. Ces informations peuvent être
enregistrées (cas d'un forum), traitées pour sortir des statistiques (cas d'un sondage) ou encore comprises comme
des ordres (panneau d'administration de site). Il est également possible d'envoyer des fichiers sans passer par le
protocole FTP.
Les formulaires sont des éléments de la page HTML affichée par le navigateur. Ils ont généralement une destination :
le script qui agit lorsque l'internaute valide le formulaire.
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.
Un formulaire est une balise HTML contenant des éléments permettant à un utilisateur de saisir des informations.
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".
-3-
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
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.
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>.
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
-4-
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
Case à cocher :
<input type="checkbox" name="checkbox_1" checked="checked" />
<input type="checkbox" name="checkbox_2" />
<input type="checkbox" name="checkbox_3" /><br />
Envoy de fichier :
<input type="file" name="file" /><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 />
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.
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).
-5-
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
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 :
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
-6-
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
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.
<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 />
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/1-5.php
Les informations envoyées au moyen d'un formulaire sont stockées dans les tableaux superglobaux de
l'environnement PHP.
-7-
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
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>';
}
?>
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'].
if(!empty($_POST)){
//
// Debug
-8-
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
//
// 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 />';
}
?>
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 !
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 />';
}
?>
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/1-8.php
if(!empty($_POST)){
//
-9-
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
//
// Récupération normale des informations
//
foreach($_POST as $field => $value){
echo '<b>'.$field.'</b> : '.$value.'<br />';
}
echo '<br /><br />';
}
?>
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/1-9.php
Il faut toujours garder à l'esprit qu'un formulaire contient des informations envoyées par l'internaute. Il n'est pas
possible de se fier à ce qu'envoie un internaute, car il peut manipuler les formulaires comme bon lui semble. L'aspect
sécurité est donc fondamental.
La meilleure pratique de sécurité est d'inclure le minimum possible de choses dans chaque formulaire. Si l'utilisateur
a déjà renseigné une information, il est préférable d'utiliser une base de données ou des sessions pour la conserver
durant sa navigation, plutôt que d'utiliser un champ de type hidden dans le formulaire (car cela donnerait à l'internaute
l'occasion de modifier cette information, ce qui peut ne pas être prévu par votre application).
De plus, il convient de filtrer les variables envoyées au moyen d'un formulaire, de manière à vérifier qu'elles
contiennent effectivement ce à quoi nous nous attendons. Il vous faut déterminer votre propre politique de filtrage
pour chaque variable transmise par formulaire.
Voici le plus courant (à tort ?) des encodages de formulaires. Il correspond à la valeur par défaut de la propriété
enctype, qu'il n'est donc pas nécessaire de spécifier. Attention à ne pas envoyer autre chose que du texte au format
ASCII avec cet entype.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/2-1.php
Il est possible de donner une valeur par défaut à un contrôle input à l'aide de sa propriété
value="". Attention, les contrôles textarea et select fonctionnent différemment.
- 10 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
La balise input type="text" a eté vue dans la première partie de ce tutoriel. Elle permet à l'internaute de saisir une
petite quantité de texte (généralement quelques dizaines de caractères), en une seule ligne.
Reprenons l'un des premiers exemples de ce tutoriel afin de mieux organiser notre code PHP.
if(!empty($_POST)){
//
// Debug
//
echo '<pre>';
print_r($_POST);
echo '</pre>';
}
?>
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/2-2.php
J'ai organisé les noms des contrôles selon la structure du formulaire. Les crochets [ ]
dans le name="" permettent de définir un nom d'index pour le tableau associatif PHP. Ici,
personal[first_name] signifie que la variable PHP correspondante est $_POST['personal']
['first_name'].
Ce champ est à utiliser avec précaution. Il donne une impression de sécurité car il n'est pas visiblement présent
dans la page. Cependant, un utilisateur averti saura en tirer parti s'il est mal utilisé. Il est donc fondamental de ne
l'introduire que dans des situations où il aura un impact minimal et contrôlé.
Un bon exemple est un formulaire pour envoyer un commentaire sur un blog. Imaginons que l'utilisateur ait suivi
un lien le conduisant à notre formulaire, qui lui permet d'entrer le titre de son message (je ne mets pas de contenu
afin de simplifier l'exemple). De manière à savoir dans quel billet le commentaire sera enregistré, il est possible
- 11 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
d'utiliser un contrôle hidden. L'utilisateur n'aurait aucun intérêt à modifier la valeur de ce champ puisque son message
n'apparaîtrait pas où il le souhaite et puisque cela ne pourrait rien lui apporter.
Le contrôle hidden permet ainsi de stocker l'identifiant (de préférence numérique) du billet de destination.
if(!empty($_POST)){
//
// Debug
//
echo '<pre>';
print_r($_POST);
echo '</pre><br />';
//
// Récupération normale des informations
//
echo '<b>Titre</b> : '.$_POST['title'].'<br />';
echo '<b>Dans le billet numéro</b> : '.$_POST['entry_id'];
echo '<br />';
}
?>
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/2-3.php
Cet élément permet de répondre à une question ne pouvant avoir qu'une seule réponse parmi une liste précise de
propositions. Il s'agit souvent d'un choix booléen (vrai ou faux) ou tout du moins ayant un nombre fixe (et peu élevé)
de réponses possibles. C'est à mon avis le plus adapté pour répondre à cette question très fréquente : "Acceptez-
vous les conditions d'utilisation de nos services (EULA) ? Oui/Non".
Pour l'utiliser, il faut répéter la propriété name="" en modifiant value="". Les boutons radio fonctionnent par groupe.
Le navigateur Web sélectionne l'un ou l'autre des éléments du groupe, jamais plusieurs à la fois. L'emplacement
dans le formulaire n'a aucune importance mais il est préférable de regrouper les boutons radio pour des questions
d'ergonomie.
if(!empty($_POST)){
//
// Debug
//
echo '<pre>';
print_r($_POST);
echo '</pre>';
}
?>
- 12 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/2-4.php
Ce contrôle permet de donner plusieurs réponses à une question donnée. Typiquement : "Quels sujets vous
intéressent ?".
J'ai expliqué plus haut qu'il est possible d'utiliser les crochets [ ] dans le nom du contrôle pour que PHP le traite
comme un tableau de valeurs. Nous allons nous en servir ici pour regrouper les checkboxes afin de les traiter plus
facilement à l'aide de la structure foreach.
if(!empty($_POST)){
//
// Debug
//
echo '<pre>';
print_r($_POST);
echo '</pre>';
//
// Récupération normale des informations
//
echo '<b>Sujets :</b><ul>';
foreach($_POST['subjects'] as $subject){
echo '<li>'.$subject.'</li>';
}
echo '</ul>';
?>
- 13 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/2-5.php
La balise textarea permet de saisir une grande quantité de texte, éventuellement sur plusieurs lignes. Des barres de
défilement sont ajoutées automatiquement par le navigateur lorsqu'elles sont nécessaires.
if(!empty($_POST)){
//
// Debug
//
echo '<pre>';
print_r($_POST);
echo '</pre><br />';
//
// Récupération normale des informations
//
echo '<b>Titre</b> : '.$_POST['title'].'<br />';
echo '<b>Message</b> : '.nl2br($_POST['message']).'<br />';
echo '<br />';
}
?>
- 14 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/2-6.php
Ici, print_r() et la balise pre se chargent de toute la mise en page. En situation réelle, les
passages à la ligne saisis dans le textarea ne sont pas visibles dans le navigateur. Il faut
utiliser la fonction nl2br() pour cela.
Il faut coller la balise ouvrante <textarea> à la balise fermante </textarea> si l'on ne souhaite
pas avoir quoi que ce soit dans la case, lors du chargement de la page. À l'inverse, si l'on veut
avoir une valeur par défaut, alors c'est à cet endroit qu'il faut la mettre.
<textarea> </textarea>
<textarea>
</textarea>
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/2-7.php
Ce contrôle est similaire aux boutons radio ou aux checkboxes, selon son utilisation. Il permet de répondre à une
question par une ou plusieurs réponses.
Il est préférable de choisir select si le nombre d'options est dynamique, car il regroupe toutes les réponses possibles
dans une case de taille fixe. Si le nombre d'options vient à changer, la structure visuelle de la page n'est pas
nécessairement modifiée dans le navigateur (contrairement aux boutons radio).
if(!empty($_POST)){
//
// Debug
//
echo '<pre>';
print_r($_POST);
echo '</pre><br />';
}
?>
- 15 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
<label>
Quelle est votre couleur préférée ?<br />
<select name="color">
<option value="bleu">bleu</option>
<option value="jaune">jaune</option>
<option value="marron">marron</option>
<option value="orange">orange</option>
<option value="rouge">rouge</option>
<option value="vert">vert</option>
<option value="violet">violet</option>
</select>
</label><br /><br />
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/2-8.php
Si ce formulaire utilisait des boutons radio plutôt qu'un select, la mise en page deviendrait rapidement difficile à
organiser.
Il est possible de spécifier l'attribut size pour donner un nombre de lignes fixe au contrôle select, afin de ne pas
obtenir une boîte déroulante.
if(!empty($_POST)){
//
// Debug
//
echo '<pre>';
print_r($_POST);
echo '</pre><br />';
}
?>
<label>
Quelle est votre couleur préférée ?<br />
<select name="color" size="5">
<option value="bleu">bleu</option>
<option value="jaune">jaune</option>
- 16 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/2-9.php
Il est également possible de spécifier l'attribut multiple afin de permettre à l'internaute de sélectionner plusieurs choix.
Si l'attribut size est absent, le contrôle prend toute la place (verticale) dont il a besoin. Il faut utiliser les crochets [ ]
pour permettre à PHP de récupérer toutes les réponses.
if(!empty($_POST)){
//
// Debug
//
echo '<pre>';
print_r($_POST);
echo '</pre><br />';
}
?>
<label>
Quelles sont vos couleurs préférées ?<br />
<select name="colors[]" size="5" multiple="multiple">
<option value="bleu">bleu</option>
<option value="jaune">jaune</option>
<option value="marron">marron</option>
<option value="orange">orange</option>
<option value="rouge" selected="selected">rouge</option>
<option value="vert">vert</option>
<option value="violet" selected="selected">violet</option>
</select>
</label><br /><br />
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/2-10.php
- 17 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
Un contrôle select ne peut avoir plusieurs options pré sélectionnées que s'il dispose de
l'attribut multiple.
Les menus déroulants peuvent devenir très longs, ce qui a tendance à noyer l'internaute dans trop d'informations.
Un moyen de pallier ce problème est d'utiliser l'élément optgroup pour grouper les options.
if(!empty($_POST)){
//
// Debug
//
echo '<pre>';
print_r($_POST);
echo '</pre><br />';
}
?>
<label>
Quelle est votre couleur préférée ?
<select name="color">
<optgroup label="Primaires">
<option value="bleu">bleu</option>
<option value="jaune">jaune</option>
<option value="rouge">rouge</option>
</optgroup>
<optgroup label="Mélanges">
<option value="vert">vert</option>
<option value="violet">violet</option>
<option value="orange">orange</option>
<option value="marron">marron</option>
</optgroup>
</select>
</label><br /><br />
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/2-11.php
- 18 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
?>
<label>
Quelles sont vos couleurs préférées ?<br />
<select name="colors[]" size="7" multiple="multiple">
<optgroup label="Primaires">
<option value="bleu">bleu</option>
<option value="jaune">jaune</option>
<option value="rouge" selected="selected">rouge</option>
</optgroup>
<optgroup label="Mélanges">
<option value="vert">vert</option>
<option value="violet" selected="selected">violet</option>
<option value="orange">orange</option>
<option value="marron">marron</option>
</optgroup>
</select>
</label><br /><br />
http://g-rossolini.developpez.com/tutoriels/php/formulaires/demo/2-12.php
Cet enctype doit être utilisé pour tous les formulaires ne contenant pas uniquement du texte au format ASCII, ce qui
le rend de plus en plus populaire en cette période de développement de l'UTF-8.
- 19 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
La gestion des contrôles déjà vus ci-dessus (input, textarea et select) ne change pas, je ne vais donc rien répéter.
La seule différence est dans la gestion du contrôle file (qui ne devrait pas être utilisé avec un enctype différent de
"multipart/form-data".
Ce contrôle permet à l'internaute de choisir un fichier de son ordinateur afin de l'envoyer au serveur Web grâce au
formulaire. Le transfert est effectué au moyen du protocole HTTP (pas de FTP ici), ce qui signifie que rien n'est
réellement prévu pour envoyer des fichiers (contrairement au FTP). Ne vous étonnez pas si vous avez du mal à
transférer des fichiers de plusieurs Mio...
Le script PHP peut faire ce qu'il souhaite avec ce fichier : il est enregistré dans un dossier temporaire du serveur Web,
ce qui signifie que sa durée de vie est limitée. Le serveur Web le supprimera certainement au bout d'un moment.
Il est ainsi possible d'utiliser le fichier comme pièce jointe d'un e-mail, de l'envoyer dans la base de données, de
l'enregistrer sur le disque du serveur, etc.
//
// Provient de la documentation PHP de la fonction ini_get()
//
function return_bytes($val) {
$val = trim($val);
$last = strtolower($val{strlen($val)-1});
switch($last) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
return $val;
}
define('MAX_FILE_SIZE', return_bytes(ini_get('post_max_size')));
if(!empty($_FILES)){
//
// Debug
//
echo '<pre>';
print_r($_FILES);
echo '</pre>';
}
?>
L'exécution de ce code nous montre que PHP récupère des informations sur chaque fichier envoyé de cette manière.
- 20 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
//
// Fonction trouvée dans la documentation de la fonction ini_get()
//
function return_bytes($val) {
$val = trim($val);
$last = strtolower($val{strlen($val)-1});
switch($last) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
return $val;
}
define('MAX_FILE_SIZE', return_bytes(ini_get('post_max_size')));
if(!empty($_FILES)){
//
// Debug
//
echo '<pre>';
print_r($_FILES);
echo '</pre>';
//
// Récupération normale des informations
- 21 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
//
// Type mime du fichier
//
if(function_exists('mime_content_type')){
// Notre système nous permet de déterminer le type réel
$type = mime_content_type($tmp_name);
}
else{
// Nous sommes contraints à faire confiance à l'internaute
$type = $_FILES['attached_file']['type'];
}
//
// Gestion des erreurs éventuelles
//
switch($error){
case UPLOAD_ERR_OK:
$error_string = 'Fichier correctement reçu';
break;
case UPLOAD_ERR_INI_SIZE:
$error_string = 'Fichier trop volumineux (php.ini)';
break;
case UPLOAD_ERR_FORM_SIZE:
$error_string = 'Fichier trop volumineux (MAX_FILE_SIZE)';
break;
case UPLOAD_ERR_PARTIAL:
$error_string = 'Fichier partiellement envoyé';
break;
case UPLOAD_ERR_NO_FILE:
$error_string = 'Fichier non envoyé';
break;
case UPLOAD_ERR_NO_TMP_DIR:
$error_string = 'Pas de répertoire temporaire';
break;
case UPLOAD_ERR_CANT_WRITE:
$error_string = "Impossible d'écrire sur le disque";
break;
}
//
// Debug
//
echo '<pre>';
print_r(array(
'name' => $name,
'type' => $type,
'error' => $error,
'size' => filesize($tmp_name),
'tmp_name' => $tmp_name,
'error_string' => $error_string
));
echo '</pre>';
}
}
?>
- 22 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
Si nous souhaitons envoyer plusieurs fichiers à la fois, il faut à nouveau utiliser les crochets [ ] dans l'attribut name
mais, cette fois, le comportement est légèrement différent. En effet, ce n'est pas $_FILES['variable'] qui est transformé
en tableau mais chacun de ses indexes.
//
// Fonction trouvée dans la documentation de la fonction ini_get()
//
function return_bytes($val) {
$val = trim($val);
$last = strtolower($val{strlen($val)-1});
switch($last) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
return $val;
}
define('MAX_FILE_SIZE', return_bytes(ini_get('post_max_size')));
if(!empty($_FILES)){
//
// Debug
//
echo '<pre>';
print_r($_FILES);
echo '</pre>';
}
?>
Nous pouvons remarquer que le tableau $_FILES['files'] se décompose ainsi (pour trois
fichiers) :
• ['name'][0]
• ['name'][1]
• ['name'][2]
• ['type'][0]
• ['type'][1]
- 23 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
• ['type'][2]
• ['tmp_name'][0]
• ['tmp_name'][1]
• ['tmp_name'][2]
• ['error'][0]
• ['error'][1]
• ['error'][2]
• ['size'][0]
• ['size'][1]
• ['size'][2]
Il n'est pas pratique d'utiliser foreach avec une telle structure. Voyons comment gérer les erreurs de plusieurs fichiers
avec une structure for.
//
// Fonction trouvée dans la documentation de la fonction ini_get()
//
function return_bytes($val) {
$val = trim($val);
$last = strtolower($val{strlen($val)-1});
switch($last) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
return $val;
}
define('MAX_FILE_SIZE', return_bytes(ini_get('post_max_size')));
if(!empty($_FILES)){
//
// Debug
//
echo '<pre>';
print_r($_FILES);
echo '</pre>';
//
// Récupération normale des informations
//
$nb_of_files = count($_FILES['attached_files']['tmp_name']);
echo '<ul>';
for($i = 0; $i< $nb_of_files; ++$i){
if(is_uploaded_file($_FILES['attached_files']['tmp_name'][$i])){
$name = $_FILES['attached_files']['name'][$i];
$tmp_name = $_FILES['attached_files']['tmp_name'][$i];
$error = $_FILES['attached_files']['error'][$i];
//
// Type mime du fichier
//
if(function_exists('mime_content_type')){
// Notre système nous permet de déterminer le type réel
$type = mime_content_type($tmp_name);
}
else{
// Nous sommes contraints à faire confiance à l'internaute
$type = $_FILES['attached_files']['type'][$i];
}
- 24 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
case UPLOAD_ERR_INI_SIZE:
echo 'Fichier trop volumineux (php.ini)';
break;
case UPLOAD_ERR_FORM_SIZE:
echo 'Fichier trop volumineux (MAX_FILE_SIZE)';
break;
case UPLOAD_ERR_PARTIAL:
echo 'Fichier partiellement envoyé';
break;
case UPLOAD_ERR_NO_FILE:
echo 'Fichier non envoyé';
break;
case UPLOAD_ERR_NO_TMP_DIR:
echo 'Pas de répertoire temporaire';
break;
case UPLOAD_ERR_CANT_WRITE:
echo "Impossible d'écrire sur le disque";
break;
}
//
// Debug
//
echo '<li>';
echo '<b>Fichier '.$i.'</b> :';
echo '<pre>';
print_r(array(
'name' => $name,
'type' => $type,
'error' => $error,
'size' => filesize($tmp_name),
'tmp_name' => $tmp_name,
'error_string' => $error_string
));
echo '</pre>';
echo '</li>';
}
}
echo '</ul>';
}
?>
- 25 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
//
// Fonction trouvée dans la documentation de la fonction ini_get()
//
function return_bytes($val) {
$val = trim($val);
$last = strtolower($val{strlen($val)-1});
switch($last) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
return $val;
}
define('MAX_FILE_SIZE', return_bytes(ini_get('post_max_size')));
define('UPLOAD_DIRECTORY', './uploads/');
if(!empty($_FILES)){
//
// Debug
//
echo '<b>$_FILES</b> :<pre>';
print_r($_FILES);
echo '</pre>';
//
// Récupération normale des informations
//
$nb_of_files = count($_FILES['attached_files']['tmp_name']);
echo '<ul>';
for($i = 0; $i< $nb_of_files; ++$i){
if(is_uploaded_file($_FILES['attached_files']['tmp_name'][$i])){
$name = $_FILES['attached_files']['name'][$i];
$tmp_name = $_FILES['attached_files']['tmp_name'][$i];
$error = $_FILES['attached_files']['error'][$i];
$clean_name = strtolower(basename($name));
$clean_name = preg_replace('/[^a-z0-9.-]/', '-', $clean_name);
//
// Type mime du fichier
//
if(function_exists('mime_content_type')){
// Notre système nous permet de déterminer le type réel
$type = mime_content_type($tmp_name);
}
else{
// Nous sommes contraints à faire confiance à l'internaute
$type = $_FILES['attached_files']['type'][$i];
}
//
- 26 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
//
// Debug
//
echo '<li>';
echo '<b>Fichier '.$i.'</b> :';
echo '<pre>';
print_r(array(
'name' => $name,
'type' => $type,
'error' => $error,
'size' => filesize($tmp_name),
'tmp_name' => $tmp_name,
'clean_name' => $clean_name,
'error_string' => $error_string
));
echo '</pre>';
echo '</li>';
}
}
echo '</ul>';
}
?>
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.
- 27 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
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
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.
<fieldset>
<legend>Autres informations</legend>
<label>
Comment nous avez-vous connus ?
<select name="referer">
<option value="friend"<?php
- 28 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
Informations personnelles
C'est ici qu'il faut demander toutes les informations civiles à notre internaute. En situation réelle, il faudrait étoffer
cette liste.
É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.
- 29 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
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.
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
?>
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.
Le début de notre script d'index doit mettre en place l'environnement : la session et les variables de configuration.
Code 3.5
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'
);
- 30 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
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
// 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 />';
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.
case 3:
// Valeurs par défaut
if(empty($_SESSION['forms'][CFG_STAGE_ID]))
{
$_SESSION['forms'][CFG_STAGE_ID] = ...
}
- 31 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
case 1:
default:
// Valeurs par défaut
if(empty($_SESSION['forms'][CFG_STAGE_ID]))
{
$_SESSION['forms'][CFG_STAGE_ID] = ...
}
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.
// 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' => ''
);
}
- 32 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
// 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
);
}
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;
}
- 33 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
IV-C - Fonctionnement
La mise en place de ces formulaires est simple : il suffit de créer l'arborescence évoquée plus haut.
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.
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.
Ce tutoriel ne traite pas des formulaires sous toutes leurs coutures. Je n'ai la prétention d'être un spécialiste ni de
JavaScript (et ses déclinaisons) ni des feuilles de style. Cependant, il est toujours utile de savoir faire le minimum...
Notez que JavaScript, CSS et PHP sont des éléments totalement indépendants. Vous avez seulement besoin du code
HTML pour le reste. La partie PHP est souvent indispensable mais certaines situations permettent de s'en passer.
Il faut prendre garde aux boutons "actualiser" et "précédent" du navigateur, car ils peuvent nous poser des problèmes.
La solution la plus simple consiste à utiliser la méthode proposée par Ramazan Korkmaz (maximenet) dans son
tutoriel : Éviter le renvoi de données POST au rafraîchissement d'une page.
Il s'agit simplement de réafficher la page avec la méthode GET, ce qui supprime les données POST et remplace la
page actuelle de l'historique du navigateur.
La fonction header()
La fonction header() nous permet d'ordonner au navigateur de demander une autre page Web. Il convient de lui
expliquer pourquoi nous lui donnons cet ordre, ce qui peut être fait à l'aide des en-têtes HTTP. Nous allons utiliser
le code HTTP 303 : "voir autre [ressource]".
- 34 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
Code 4.1
header('HTTP/1.1 303 See Other');
header('Location: script.php');
exit;
Le mot clef exit nous assure que le navigateur ne chargera pas d'informations inutiles.
Dans les exemples de formulaire réparti sur plusieurs pages (présents dans de ce tutoriel), il
faut empêcher l'exécution systématique de la commande echo implode() en la remplaçant
par ceci :
Code 4.2
if(empty($_POST))
{
echo implode(' - ', $items).'<br /><br />';
}
Afin d'obtenir un formulaire optimal, il est préférable d'effectuer dès que possible tous les traitements sur les données
soumises par l'utilisateur. Cela permet d'enregistrer le contenu d'un formulaire dans une variable de session ou dans
une base de données avant d'avoir envoyé quoi que ce soit au navigateur, nous permettant ainsi d'utiliser la fonction
header().
Dans certains cas, JavaScript peut être très utile dans les formulaires. D'après le W3C, un formulaire ne peut être
envoyé que si tous les contrôles (ayant un nom et une valeur), ainsi que quelques exceptions, sont valides. Le bouton
submit qui a été cliqué fait partie des contrôles qui doivent être valides pour que le navigateur envoie le formulaire.
Cela nous permet d'effectuer un traitement JavaScript en utilisant l'évènement onsubmit du bouton submit. La fonction
JavaScript appelée permettra éventuellement d'invalider le bouton submit et ainsi de ne pas soumettre le formulaire.
C'est particulièrement utilisé pour les mots de passe.
L'attribut HTML id est utilisé par la fonction JavaScript document.getElementById(). C'est celui
que nous utiliserons, plutôt que l'attribut name qui est destiné à PHP (mais qui peut avoir la
même valeur, ce qui est d'ailleurs assez courant).
Il faut toujours se souvenir que JavaScript est une technologie client, elle n'est donc pas
exécutée dans l'environnement de confiance qu'est notre serveur Web. L'internaute peut
désactiver le JavaScript ou s'arranger pour pour passer outre nos vérifications en JavaScript,
ce qui fait que le script PHP ne devra absolument pas s'y fier. Les seules vérifications valides
(point de vue sécurité) sont celles effectuées par le script PHP. Le script JavaScript ne permet
que d'améliorer l'expérience utilisateur en évitant de soumettre un formulaire s'il n'est pas
correctement rempli. Une vérification en JavaScript ne doit pas se substituer à une vérification
en PHP, mais elle peut la compléter ou la renforcer. Il ne faut pas partir du principe qu'un
formulaire reçu par PHP est un formulaire valide : l'internaute peut être en train de pirater
(s'amuser avec) notre site.
- 35 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
if(!empty($_POST)){
//
// Debug
//
echo '<pre>';
print_r($_POST);
echo '</pre>';
//
// Récupération normale des informations
//
$missing_fields = array();
if(empty($_POST['login'])){
$missing_fields[] = '"login"';
}
if(empty($_POST['e_mail'])){
$missing_fields[] = '"e_mail"';
}
if(empty($missing_fields)){
- 36 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
?>
function is_filled(){
missing_fields = '';
if(document.getElementById("login").value == ""){
missing_fields += "\n 'login'";
}
if(document.getElementById("e_mail").value == ""){
missing_fields += "\n 'e_mail'";
}
if(missing_fields == ""){
return true;
}
else{
alert("Les champs suivants doivent être remplis :" + missing_fields);
return false;
}
}
</script>
<?php
if(!empty($_POST)){
//
// Debug
//
echo '<pre>';
print_r($_POST);
echo '</pre>';
//
// Récupération normale des informations
//
$missing_fields = array();
if(empty($_POST['login'])){
$missing_fields[] = '"login"';
}
if(empty($_POST['e_mail'])){
$missing_fields[] = '"e_mail"';
}
if(empty($missing_fields)){
echo 'Tous les champs ont été renseignés';
}
else{
echo 'Les champs suivants doivent être remplis :<br />';
echo implode('<br />', $missing_fields);
}
- 37 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
<form method="post"
action="<?php echo basename(__FILE__); ?>"
enctype="multipart/form-data"
onsubmit="return is_filled();">
<label>
Nom d'utilisateur * :
<input type="text" name="login" id="login" />
</label><br />
<label>
Adresse e-mail * :
<input type="text" name="e_mail" id="e_mail" />
</label><br />
<label>
Numéro de téléphone :
<input type="text" name="phone" id="phone" />
</label><br />
<label>
Adresse :
<input type="text" name="address" id="address" />
</label><br /><br />
if(!empty($_POST)){
//
// Debug
//
echo '<pre>';
print_r($_POST);
echo '</pre>';
//
// Récupération normale des informations
//
if($_POST['password_1'] != $_POST['password_2']){
echo 'Erreur de mot de passe';
}
else{
echo 'Le mot de passe a été correctement saisi';
}
echo '<br /><br />';
}
?>
- 38 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
</script>
<?php
if(!empty($_POST)){
//
// Debug
//
echo '<pre>';
print_r($_POST);
echo '</pre>';
//
// Récupération normale des informations
//
if($_POST['password_1'] != $_POST['password_2']){
echo 'Erreur de mot de passe';
}
else{
echo 'Le mot de passe a été correctement saisi';
}
echo '<br /><br />';
}
?>
<form method="post"
action="<?php echo basename(__FILE__); ?>"
enctype="multipart/form-data"
onsubmit="javascript: return check_password('password_1', 'password_2');">
<label>
Nom d utilisateur :
<input type="text" name="login" id="login" />
</label><br />
<label>
Mot de passe :
<input type="password" name="password_1" id="password_1" />
</label><br />
<label>
Vérification :
<input type="password" name="password_2" id="password_2" />
</label><br /><br />
Les formulaires HTML ont une interface qui varie selon le navigateur utilisé et selon la configuration de ce navigateur
(thèmes-skins, etc.) et cela ne correspond pas toujoursà la charte graphique de notre site Web.
Les feuilles de style (CSS) sont là pour nous aider.
- 39 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
Nous utiliserons l'attribut HTML class pour définir l'apparence de nos formulaires.
/* BODY */
body {
color: Black;
background-color: #DDEEFF;
font-family: Arial, Verdana, sans-serif;
font-size: 13px;
}
/* FORMULAIRE */
/* balises INPUT */
input {
background-color: #FAFAFA;
border-width: 1px;
border-color: #D1D7DC;
color: Black;
font-style: italic;
}
/* LEGEND : titre */
.form legend {
border: solid;
border-width: 1px;
border-color: Black;
padding: 5px;
background-color: #6389D8;
font-weight: bold;
color: White;
font-size: 14px;
}
- 40 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
</style>
<?php
if(!empty($_POST)){
//
// Debug
//
echo '<pre>';
print_r($_POST);
echo '</pre>';
}
?>
<div id="submit">
<input type="submit" value="Envoyer" />
<input type="reset" value="Rétablir" />
</div>
</form>
VI - Conclusion
VI-A - Épilogue
Nous avons vu comment utiliser les formulaires en HTML et comment les agrémenter de quelques fonctionnalités
supplémentaires (style et script). Attention, certains navigateurs ne respectent pas la norme : avec certains d'entre
eux, le <label> peut ne pas donner le focus à son contrôle associé. Par ailleurs, n'accordez pas toute votre confiance
aux vérifications effectués au moyen d'un script côté client car il est très facile de déjouer ce genre de méthodes :
implémentez les mêmes vérifications côté serveur. Enfin, limitez au maximum les informations à transmettre par
formulaire, à cause de la simplicité de falsification : préférez une session PHP ou, mieux, une base de données.
VI-B - Liens
Liens de Developpez
• Vérifier une saisie utilisateur (formulaire)
• La FAQ JavaScript de Developpez.com
• Les cours HTML, XHTML et CSS de Developpez.com
• Tutoriel : Utiliser une base de données pour sécuriser vos sessions, par Adrien Pellegrini
Liens externes
• HTML 4 : Documentation du W3C sur les formulaires
- 41 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/
Les formulaires et PHP5 par Guillaume Rossolini
- 42 -
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.
http://g-rossolini.developpez.com/tutoriels/php/formulaires/