Accueil

Traduction

Débuter en programmation web - sommaire

Débuter en programmation web - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

PHP et les formulaires de soumission

Dans ce chapitre nous abordons une des missions essentielles de PHP : traiter les données envoyées par un formulaire de soumission.
Ces données sont non seulement des textes mais peuvent être aussi des fichiers (des images par exemple).
Les traitements PHP évoqués dans ce chapitre resteront basiques mais essentiels : apprendre à manipuler le tableau associatif découlant d'une soumission ($_GET[] ou $_POST[]) ou $_FILES[]).
Prérequis pour aborder ce chapitre vous devez connaitre les variables et tableaux associatifs en PHP.
Je vous invite donc à revoir éventuellement le chapitre en lien ci-dessous.
Les variables et tableaux de données en PHP

Transmettre des données avec l'URL

Mais avant d'aborder les formulaires et le traitement des donnée soumissionnées, je voudrais vous montrer qu'il est possible de passer des données dans la page cible via l'URL.
URL signifie "Uniform Ressource Locator" et représente une adresse sur le web.
Dois-je vous rappeler que l'URL apparait dans la barre d'adresse du navigateur.
L'URL c'est aussi la valeur de l'attribut href de l'élément A (lien hypertexte).
Et bien sachez qu'il est possible d'ajouter à cette URL des paramètres.

Testez un micro site

Cliquez ici

Cliquez successivement sur les liens qui s'affichent (accueil, page1, page2 et page3)
Dans chacune des pages il est affiché :

	Page d'accueil du site OU première / deuxième / troisième page du site 
	Site réalisé par 
	Darcheville Patrick
	le nom de la page : index.php / page1.php /page2.php /page3.pho

Observez attentivement la barre d'URL !

Si vous avez cliqué sur le deuxième lien, vous lisez :
https://darchevillepatrick.info/php2/page1.php?nom=Darcheville&prenom=Patrick
Donc l'URL indique non seulement la page cible mais contient aussi des paramètres.

Le code de ce micro site

Le code de la page "index.php"

Les trois autres pages du site ont un code quasi identique sauf le contenu de l'élément H3 et du dernier BR.

Les fichiers d'inclusion

Le code de "debut.htm"

Observez la feuille de style pour réviser votre CSS !
Le site est 'responsive' puisque la largeur de BODY est exprimé en %.

Le code du fichier "navigation.htm"

La lecture du code ci-dessus doit vous surprendre.
La valeur de l'attribut href contient non seulement le chemin vers la page web cible mais aussi des paramètres.
On peut donc transférer vers la page cible autant de paramètres qu'on veut à condition d'écrire un "?" après le lien proprement dit et de séparer les données par le symbole "&".

On peut modifier / supprimer les données transmises via l'URL

N'ayant pas fermé l'onglet dans lequel le micro site est affiché, sélectionnez le !

Modifiez les paramètres

Cliquez sur "accueil" et modifiez le contenu de la barre d'adresse comme suit : :
http://darchevillepatrick.info/php2/index.php?nom=Dupont&prenom=Jacques
Puis appuyez sur ENTER.
Essayez !
La page affiche désormais que le site a été réalisé par Dupont Jacques ...

Supprimer les paramètres

Cliquez sur "accueil" puis modifier le contenu de la barre d'adresse comme suit : :
http://darchevillepatrick.info/php2/index.php
Appuyez sur ENTER.
Essayez !
La page affiche ni nom ni prénom.

Bien évidemment dès que vous cliquez sur un autre lien, la page affiche de nouveau mon nom et prénom puisque le lien hypertexte retransmet à nouveau ces paramètres.

Transmettre des données via un formulaire par la méthode GET

Testez le site "les pages jaunes"

Par exemple allez sur le site "pagesjaunes" et renseignez le formulaire de la page d'accueil :
Autorisez la géolocalisation.
Dans le formulaire saisir "hotel" et dans la deuxième zone de texte sélectionner "autour de moi"

La barre d'adresse contient alors :
https://www.pagesjaunes.fr/annuaire/chercherlespros?quoiqui=hotels&ou=Autour+de+moi&univers=pagesjaunes& idOu=&accuracy=1793.7118307086605&latitude=51.003392&longitude=2.2904832
Ce qui veut dire que le formulaire du site "pagesjaunes" utilise la méthode GET !

les pages jaunes

Remarques

Le formulaire proposé par le site les "pages jaunes" est basé sur la méthode GET !

Lorsque les données du formulaire sont soumissionnées avec la méthode GET ces données apparaissent dans la barre d'URL et peuvent donc être modifiées par le visiteur.

Insérer des paramètres dans les liens ou envoyer ces données de formulaire avec la méthode GET sont deux techniques qui aboutissent au même résulat : ces données transitent par l'URL.

Transmettre des données via un formulaire avec la méthode POST

Pour des raisons de confidentialité n'utilisez jamais un formulaire basé sur la méthode GET pour saisir des identifiants et mot de passe car ces données vont être affichées dans la barre d'URL à la vue de tous.
Utilisez un formulaire avec la méthode POST.

Thématique : nous devons concevoir un formulaire d'inscription à un site.

Dans une première solution on va utiliser deux pages : l'une contenant le formulaire de soumission et une autre pour le traitement des données soumissionnées.

La page contenant le formulaire d'inscription

La page se nomme "inscription_form.php".
Elle pourrait avoir pour extension .htm puisqu'elle ne contient pas de code PHP mais il est plus simple que dans un site toutes les pages aient la même extension.

La feuille de style interne du document HTML

	label, input {width : 40% ; display : inline-block ; margin :10px ; }
	input:valid {color : green ; }
	input:invalid {color : red; }

emploi des pseudo-classes :valid et :invalid.
Tant qu'une saisie dans un champ est invalide (saisie ne correspondant pas au type ou au "patron" (défini dans l'attribut pattern) elle apparaît en rouge ; dès que la saisie est correcte elle apparaît en vert.

Le code du formulaire

les données sont envoyées dans la page "inscription_trait.php" avec la méthode POST.
Le formulaire comprend quatre champs car il faut saisir deux fois l'identifiant (une adresse mail) et deux fois le mot de passe.

Notez l'emploi du type "email" et des attributs HTML required, pattern pour les champs "text" et "password".
Il s'agit de contrôles de saisie HTML5.

Le code de la deuxième page - celle traitant les données

La page se nomme "inscription_trait.php" c'est à dire la valeur de l'attribut action dans le formulaire.

Le code de la page cible "inscription_trait.php"

Testez

Formulaire de soumission avec un contrôle JS

Reprenons le même thème avec en plus un contrôle de saisie écrit en JS.

Le formulaire de soumission présenté dans le paragraphe précédent est pas mal mais il souffre d'une lacune. On accède à la page cible ("insription_trait.php") même les deux adresses mail ou les deux mots de passe sont différents (mais valides vis à vis du type ou du 'patron').
C'est quand même génant d'adresser à la page cible des données fausses.
Le contrôle "côté client" (ou "côté navigateur") des saisies est insuffisant. Il faut rajouter un script en JS !

Testez !

Le code HTML et CSS de la page "inscription_form2.php"

Il est strictement identique à la version précédente sauf rajout d'un élément H3 vide avant la balise FORM fermante.
< h4 id ="message"></h4>

Le script

var message = document.querySelector('#message') ; 
document.querySelector('form').onsubmit = function(event) 
{
  if (f.mail1.value == f.mail2.value && f.passe1.value == f.passe2.value)
	{message.textContent = "Saisie correcte ! " ; }
  
  else
  {
    event.preventDefault(); // annulation de la soumission
    message.textContent = "Erreurs de saisie !" ; 
  }
  
} // fin fonction anonyme

Ce script est écrit en JS moderne.
Je ne commenterai pas ce code ici.
Vous trouverez dans mon site un tuto JavaScript et plus particulièrement tout un chapitre sur JS et les formulaires.
JavaScript et les formulaires

Formulaire et traitement PHP dans une page unique : "inscription_form3.php"

Cette page, contenant un script PHP, doit obligatoirement avoir l'extension .php

Testez !

Notez la grande ergonomie de cette page.
Tant que la soumission n'est pas validée par le script JS, les données saisies restent affichées et on peut les corriger.
Dès qu'il y a soumission le résultat du traitement PHP s'affiche sous le formulaire.

Le code de cette page unique

Structure de la page unique

Il s'agit d'une page web avec du CSS, du HTML, du JS et du PHP !

Le formulaire

Concernant le code du formulaire la seule différence par rapport aux deux versions précédentes, se se situe au niveau de l'instruction FORM :
...form name ="f" action = "#" method ='post' ...
La valeur de l'attribut action est désormais "#" ce qui veut dire "cibler la même page".
La valeur de cet attribut peut être aussi le nom de la page web : "inscription_form3.php".

Les scripts

Je ne vous communique que le script PHP car c'est l'occasion de rappeler la technique du 'hachage' du mot de passe.
Pour en savoir plus le 'hachage', revoyez le chapitre sur les fonctions PHP : Cliquez ici !

Travaux pratiques

Je ne peux que vous conseiller de récréer tout le code de "inscription_form3.php".
Si vous avez assimilé tout ce que vous avez lu, vous devriez ne pas avoir de difficultés.

Boutons radio & cases à cocher & listes

Dans un formulaire il n'y a pas que des zones de texte (avec contenu visible ou masqué ; zones monoligne ou multilignes). En d'autres termes, il n'y pas que des "input text, input password ou textarea".

Je vous propose un formulaire qui comprend un groupe de boutons radio, un groupe de cases à cocher, une liste à choix unique et une liste à choix multiple.
Je vous rappelle que pour créer un groupe de boutons radio il faut leur donner le meme nom et qu'on ne peut alors cocher qu'un bouton.
On peut donner le même nom à un groupe de case à cocher mais le nom doit alors comprendre des crochets terminaux ; même remarque pour une liste à choix multiple.

Exemple de page unique : formulaire & traitement PHP

Le code du formulaire

Notez le nom du groupe de cases à cocher et de la liste à choix multiple : gouts[] & sports[]. Les crochets sont obligatoires ; ils précisent que les "value" des cases "checked" ou des items "selected" seront ajoutées dans un tableau.

Le script PHP

Le traitement PHP est lancé seulement si la variable $_POST['sexe'] existe donc si soumission effectuée.

Le traitement du groupe de boutons radio est tres simple puisqu'une seule valeur saisie ; même remarque pour la liste à choix unique.

Par contre le traiement du groupe de cases à cocher OU d'une liste à choix multiple est plus complexe puisque plusieurs valeurs peuent être saisies (cases "checked" ou items "selected").
Il faut une boucle pour parcourir les différents items du tableau $_POST['gouts'] et une autre pour parcourir ceux du tableau $_POST['sport').

Le rendu dans un iframe

Sélectionnez plusieurs couleurs et plusieurs sports avant de soumissionner.

Les résultats du traitement apparaissent sous le formulaire.

Prolongements

Dans la réalité le traitement PHP des textes soumissionnés est souvent plus complexe.
Illustrons par deux exemples.

Exemple 1 : inscription à un site (création de son espace perso)

Après controle de validité "côté serveur" (donc en PHP) il faut créer un nouvel enregistrement dans la table des inscrits pour y mémoriser de façon permanente l'identifiant et le mot de passe 'haché'.

Exemple 2 : connexion à son espace perso

Le mot de passe saisi doit être 'haché'.
Il y a ensuite une recherche indexée dans la table des inscrits à partir des critères identifiant et mot de passe crypté.
Si la recherche est fructueuse la connexion est autorisée : accès à différentes pages / informations. Sinon message d'erreur "Identifiant / mot de passe incorrects".

Pour résumer

En d'autres termes il faut manipuler la base de données associée au site.
Le script PHP doit alors appeler des requêtes SQL (requêtes SELECT et requêtes action).
Je n'en dis pas plus plus ; la manipulation en PHP d'une base de données est évoquée dans le chapitre en lien.
Un site avec une base de données MySQL

Envoi d'un fichier

Lorsque vous publiez des photos sur Facebook, vous téléversez des fichiers vers ce site. On dit aussi que vous "uploadez" vers cette plateforme.
Pour envoyer des images et de façon générale des fichiers vers un site il faut disposer d'un formulaire de soumission avec des particularités :

Le code du formulaire

Je vous propose le code HTML d'un formulaire de soumission qui permet d'envoyer une image.

Pour l'envoi d'un fichier il faut donner la valeur "multipart/form-data" à l'attribut enctype. À défaut le destinataire ne recevra qu'une chaîne de caractères contenant le nom et le chemin de ce fichier sur le disque dur de l'expéditeur.

Il est également possible de limiter la taille du fichier à envoyer. Il suffit d'ajouter un champ masqué nommé max_file_size et de préciser la valeur de la taille maximale acceptée (en octets).

Un input type file vous permet de naviguer dans l'arbrescence pour choisir un dossier puis sélectionner un fichier.
Grâce à la valeur de l'attribut accept il y aura filtrage. Ainsi dans l'exemple ci-dessus seuls les images .gif, .jpeg et .jpg sont affichées.
Notez bien que le "input type file" a ici pour nom "nom_image".

On peut envoyer plusieurs fichiers au serveur si le formulaire comprend plusieurs "input file".

Le code de la page cible : "envoi_image_trait.php"

Commentaire du script PHP

Pour chaque fichier envoyé, un tableau associatif $_FILES['nom_du_champ'] est créé. Donc ici ce sera $_FILES['nom_image'] puisque le champ de type file se nomme "nom_image".
Quelques éléments de ce tableau associatif : ['name'], ['type'], ['size'], ['tmp_name'], ['error'] c'est à dire respectivement : nom, type et taille du fichier, emplacement provisoire et code_erreur.

$info_fichier = pathinfo($_FILES['nom_image']['name'] : $info_fichier est un 'array' contenant différentes infos sur le fichier. En effet la fonction pathinfo() appliquée à $_FILES['nom_image']['name'] retourne un 'array' dont les éléments contiennent des infos sur le fichier.
$extension = $info_fichier['extension'] : $extension contient l'extension du fichier.

Le rendu dans un nouvel onglet

Cliquez ici pour tester le code !

Vous n'avez pas besoin de saisir le nom du fichier à "uploader" vers le serveur ; une boite de dialogue apparait.
La page cible se contente d'afficher quelques caractéristiques de l'image 'uploadée" : nom, type, taille, emplacement provisoire du fichier, code erreur (0 : pas d'erreur de chargement).

Soumission d'un fichier : script professionnel

Remarque

Le traitement PHP que je vous ai proposé ci-dessus est très incomplet.

Ces différentes conditions remplies, il faut alors accepter le "upload" en transférant le fichier du dossier temporaire vers le dossier définitif.

Le code de "envoi_image_trait2.php"

Remarque: le formulaire de soumission est contenu dans le document "envoi_image2.htm" dont le code est strictement identique à "envoi_image.htm" sauf bien sûr la valeur de l'attribut action.

Analyse détaillée du script

Ce code exige plusieurs explications ...

Pour vérifier si une image a bien été envoyée il suffit de vérifier si la tableau $_FILES a bien été créé et si le code erreur est 0 (absence d'erreur).

Pour contrôler la taille de l'image soumissionnée il suffit de tester $_FILES['mon_image']['size'] 

Pour vérifier l'extension du fichier envoyé c'est un plus compliqué ...
Dans le paragraphe précédent j'ai déjà évoqué la fonction pathinfo().
$extension_image = $info_image['extension'] : je récupère l'extension du fichier.
$extensions_valides = array('jpg','jpeg', 'gif','png') : je crée un tableau avec toutes les extensions valides.
if(in_array($extension_image, $extensions_valides)) : si le contenu de $extension_image est un élément du tableau $extensions_valides ?

Si tous ces tests sont true alors il faut stocker l'image dans un dossier définitif.
Je veux envoyer l'image dans le dossier "../debutant" avec le nom d'origine de l'image.
Le dossier "debutant" existe déjà.

Il faut utiliser la fonction move_uploaded_file() pour effectuer ce transfert. Cette fonction a besoin de deux paramètres : le chemin "source" et le chemin "destination".

Le chemin "source" est simple : $_FILES['nom_image']['tmp_name']

Le chemin "destination" est plus complexe.
Aussi il faut appliquer la fonction basename() au chemin "source" pour ne garder que le nom du fichier.
On obtient donc le chemin "destination" avec l'expression : '../debutant/'.basename($_FILES['nom_image']['name'])

Le rendu

Le transfert de fichiers présente un problème de sécurité majeur. En effet ces fichiers "uploadés" vont être écrits voire exécutés sur le serveur.
Vous comprenez donc que je ne vous accorde pas le droit de tester le script ci-dessus dans mon site.
La solution : reconstituez le code des deux pages et testez en local avec Wampserver OU testez sur votre propre site.
N'oubliez pas de vérifier les droits du dossier cible : vérifiez le CHMOD du dossier !

CHMOD, c'est quoi ???
Je vous renvoie au chapitre sur la gestion des fichiers en PHP : PHP et les fichiers

Génération de formulaire via PHP

Il peut être intéressant de générer tout ou partie du code d'un formulaire de soumission via un script PHP. En particulier si ce dernier comprend plusieurs champs de même nature.

Exemple - le code

Thème : dans une matière chaque élève a au moins au maximum 5 notes.
Le professeur veut réaliser une application PHP qui permet de calculer la moyenne de chaque élève. <

Le code ci-dessous :

Surtout n'oubliez pas les crochets pour le nom du champ INPUT : notes[] afin que $_POST['notes'] soit un 'array'.

Le traitement doit fonctionner même si certains champs numériques n'ont pas été renseignés : La fonction array_filter() supprime les éléments vides du tableau $notes.

Le rendu

Saisissez moins de 5 notes, validez et observez.

Variante

On peut imaginer une solution plus flexible : l'internaute saisit le nombre de notes de l'élève et alors un script PHP génère le nombre d'input number correspondant.