Blog ENI : Toute la veille numérique !
Dernière chance (fin le 29/02) : -25€ dès 75€ sur les livres en ligne, vidéos... code FUSEE25. J'en profite !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. PHP 8
  3. Gérer les formulaires et les liens
Extrait - PHP 8 Développez un site web dynamique et interactif (2e édition)
Extraits du livre
PHP 8 Développez un site web dynamique et interactif (2e édition) Revenir à la page d'achat du livre

Gérer les formulaires et les liens

Vue d’ensemble

1. Introduction

Dans les sites web dynamiques, il est très souvent nécessaire d’interagir avec l’utilisateur. 

En HTML, il existe principalement deux méthodes pour interagir avec un utilisateur :

  • les liens (balise <a>) ;

  • les formulaires (balise <form>).

Des scripts PHP peuvent être utilisés pour traiter le clic de l’utilisateur sur un lien ou la saisie de l’utilisateur dans un formulaire.

2. Les liens

Le lien est la technique de base qui permet à un utilisateur de naviguer entre les différentes pages d’un site.

Un lien HTML est défini entre les balises <a> et </a>.

Syntaxe simplifiée

<a  
  [ href="url" ] 
  [ id="identifiant_lien" ] 
  [ target="cible" ] 
> 
... 
</a> 

Les attributs de la balise <a> sont les suivantes :

href

URL (Uniform Resource Locator) relative ou absolue qui est appelée par le lien.

id

Identifiant du lien. Si la page HTML contient plusieurs liens, l’identifiant permet de les différencier. En ce qui nous concerne, cet identifiant ne présente pas d’intérêt car il n’est pas récupéré dans le script de traitement du lien. Par contre, il peut être utilisé côté client, en JavaScript par exemple.

target

Cible (par exemple une autre fenêtre) dans laquelle ouvrir l’URL cible. Par défaut, l’URL cible s’affiche dans la même fenêtre.

L’URL peut contenir des paramètres qui permettent de passer des informations d’une page à une autre.

Syntaxe

url_classique?nom=valeur[&...] 

Le point d’interrogation (?) introduit la liste des paramètres de l’URL séparés par le caractère esperluette (&) ; chaque paramètre est constitué par un couple nom/valeur sous la forme nom=valeur :

www.monsite.com/info/accueil.php?prenom=Olivier  
chercher.php?prenom=Olivier&nom=HEURTEL 

Exemple

  • Script page1.php

<?php 
// Initialisation d'une variable. 
$nom='Olivier'; 
?> 
<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr"> 
  <head><meta charset="utf-8"...

Récupérer les données passées par l’URL

1. Considérations

a. Que se passe-t-il si deux paramètres portent le même nom ?

C’est tout simplement le dernier paramètre rencontré dans l’URL qui fixe la valeur.

Exemple

<a href="page2.php?nom=Olivier&nom=Xavier">Page 2</a> 

Cette URL donne une seule variable nom égale à Xavier dans le tableau $_GET.

b. Utiliser un tableau pour passer des données dans l’URL

Il est possible d’utiliser une notation de type tableau dans le nom du paramètre passé dans l’URL.

Exemple

<a href="page2.php?data[]=HEURTEL&data[]=Olivier">Page 2</a> 

Cette URL donne une variable data, de type tableau, qui contient les lignes suivantes :

Clé

Valeur

0

HEURTEL

1

Olivier

PHP remplit le tableau en ajoutant une ligne pour chaque paramètre, avec un indice entier consécutif commençant à 0 (comme pour la notation [] étudiée dans le chapitre Introduction à PHP - Les bases du langage PHP - Tableaux).

Cette technique est intéressante, mais, dans le code, il faut savoir que l’indice 0 correspond au nom et l’indice 1 au prénom. Par ailleurs, un problème peut se présenter si l’ordre des paramètres change.

Pour améliorer cette technique, il est possible de fixer soi-même la clé, soit avec un numéro, soit avec une chaîne de caractères.

Exemple

<a href="page2.php?data[nom]=HEURTEL&data[prénom]=Olivier">Page 2</a> 

Cette URL donne le résultat suivant dans le tableau data :

Clé

Valeur

nom

HEURTEL

prénom

Olivier

2. Transmettre des caractères spéciaux

Si la valeur à transmettre ne contient pas de caractères spéciaux (espace, esperluette (&), point d’interrogation (?), etc.), elle peut être placée directement dans l’URL comme indiqué précédemment. Dans le cas contraire, il est nécessaire de l’encoder pour éviter que ces caractères particuliers soient mal interprétés.

Par exemple, si la donnée passée dans l’URL contient "Olivier & Xavier", seul "Olivier" sera récupéré à...

Récupérer les données saisies dans le formulaire

1. Considérations

a. Que se passe-t-il si deux zones portent le même nom ?

C’est tout simplement la dernière zone rencontrée dans le formulaire qui fixe la valeur.

Exemple

<form action="saisie.php" method="POST"><div> 
Nom : <input type="text" name="nom"><br /> 
Prénom : <input type="text" name="nom"><br /> 
<input type="submit" name="ok" value="OK"> 
</div></form> 

La saisie de HEURTEL dans la première zone et de Olivier dans la deuxième donne une seule valeur égale à Olivier dans le tableau $_POST.

b. Que se passe-t-il s’il y a deux formulaires dans la page HTML ?

Les variables ne sont créées et renseignées que pour le formulaire qui a été validé.

Exemple

<form action="saisie.php" method="POST"><div> 
Nom 1 : <input type="text" name="nom1"><br /> 
<input type="submit" name="ok1" value="OK1"> 
</div></form> 
<form action="saisie.php" method="POST"><div> 
Nom 2 : <input type="text" name="nom2"><br /> 
<input type="submit" name="ok2" value="OK2"> 
</div></form> 

Si l’utilisateur valide le premier formulaire, la valeur nom1 sera disponible. Si l’utilisateur valide le deuxième formulaire, c’est la valeur nom2 qui sera disponible.

c. Utiliser un tableau pour récupérer les données saisies

Il est possible d’utiliser une notation de type tableau dans l’attribut name des balises <input>, <select> et <textarea>.

Exemple

<form action="saisie.php" method="POST"><div> 
Nom : <input type="text" name="saisie[]"><br /> 
Prénom : <input type="text" name="saisie[]"><br /> 
<input type="submit" name="ok" value="OK"> 
</div></form> 

La saisie de HEURTEL dans la première zone et de Olivier dans la deuxième donne une seule variable...

Contrôler les données récupérées

1. Vue d’ensemble

Dans la première partie de ce chapitre, nous avons vu comment récupérer les données passées dans une URL ou saisies dans un formulaire.

Ensuite, il faut vérifier que les données récupérées sont correctes, c’est-à-dire qu’elles respectent les règles de gestion définies pour l’application.

Pour la sécurité du site, il convient d’être suspicieux vis-à-vis des données qui viennent de l’extérieur (formulaire, URL, mais aussi, nous le verrons plus tard, cookie, etc.). Ces données doivent être contrôlées, filtrées, pour éviter les attaques potentielles d’un utilisateur mal intentionné.

L’objectif de cette partie est de vous fournir quelques pistes sur les techniques couramment utilisées en PHP pour cette vérification. Une autre approche possible consiste à réaliser un contrôle en JavaScript dans le navigateur, l’intérêt étant d’éviter un aller et retour avec le serveur.

Les différents exemples présentés dans cette partie utilisent des formulaires. Les mêmes vérifications doivent être effectuées sur les données passées dans une URL.

2. Vérifications classiques

a. Nettoyage des espaces indésirables

La fonction trim (cf. chapitre Utiliser les fonctions PHP - section Manipuler les chaînes de caractères) peut être utilisée pour supprimer les "blancs" indésirables en début et/ou en fin de chaîne. Dans le cas d’un formulaire, ce traitement s’applique notamment aux zones en saisie libre (<input> de type text ou password, <textarea>).

Exemple

// Récupérer la valeur saisie dans la zone "nom" et nettoyer 
// les espaces qui traînent (au début et à la fin) 
$nom = trim($_POST['nom']); 

b. Données obligatoires

Tester si une donnée obligatoire est présente se révèle très simple : il suffit de tester si la variable associée contient une valeur.

Exemple

$nom = trim($_POST['nom']); 
if ($nom == '') { ...

Problèmes sur les données récupérées

Un problème d’affichage dans une zone de formulaire peut se produire si la donnée affichée contient un guillemet (").

Exemple

images/07RI20.PNG
images/07RI21.PNG

Source de la page dans le navigateur (extrait)

    <form action="saisie.php" method="post"> 
    <div> 
      Saisie : <input type="text" name="saisie" 
                      value="il dit : "bonjour !"" /> 
      <input type="submit" name="ok" value="OK" /> 
      <br />il dit : "bonjour !" </div> 
    </form> 

En HTML, dans les attributs des balises (value, name...), le délimiteur de chaîne est le guillemet. Dans l’attribut value, la séquence "il dit : " est considérée comme la valeur de l’attribut et le reste de la chaîne est ignoré. Le problème se produit même si le guillemet est échappé par le caractère \ car ce dernier n’est pas un caractère d’échappement en HTML.

Un autre problème d’affichage se produit dans la page si la donnée affichée contient des balises HTML.

Exemple

images/07RI22.PNG

La saisie Olivier <b>Heurtel donne le mot Heurtel en gras lors de l’affichage dans la page HTML. La séquence <b> saisie par l’utilisateur se retrouve telle quelle dans le code source de la page et est donc interprétée par le navigateur comme la balise de mise en gras.

Enfin, nous pouvons rencontrer un troisième problème lors de la saisie dans une zone de commentaire.

Exemple

images/07RI23.PNG

Une saisie sur plusieurs lignes dans la zone <textarea> est bien réaffichée telle quelle dans la zone mais est affichée sans les sauts de ligne dans la page HTML. Le texte est bien présent avec des sauts de ligne dans le code source de la page, mais le saut de ligne, en dehors d’une zone <textarea>, n’est pas interprété par le navigateur : il faut mettre une balise <br />.

Nous voyons donc apparaître trois problèmes relatifs à l’affichage dans la page HTML de données...

Utilisation des filtres

1. Principes

Cette extension permet de filtrer et valider des données, notamment celles provenant de la saisie des utilisateurs.

Chaque filtre est défini par un numéro (identifiant), un nom et éventuellement des options et des indicateurs qui précisent le comportement du filtre. Chaque option est définie par un nom qui est utilisé comme clé dans un tableau associatif. Chaque indicateur est défini par une constante ; pour spécifier plusieurs indicateurs, il suffit de sommer les constantes correspondantes.

Quelques exemples de filtres (voir la documentation pour la description de tous les filtres) :

Identifiant (constante prédéfinie)

Description

FILTER_VALIDATE_INT

Valide une valeur en tant qu’entier. Les options min_range et max_range permettent de définir un intervalle de validité. 

FILTER_VALIDATE_FLOAT

Valide une valeur en tant que nombre à virgule flottante. Une option decimal permet de spécifier le caractère utilisé comme séparateur décimal et une option thousand le caractère utilisé comme séparateur de milliers. Les options min_range et max_range permettent de définir un intervalle de validité. Pour autoriser la présence des séparateurs de milliers, il faut en plus utiliser l’indicateur FILTER_FLAG_ALLOW_THOUSAND.

FILTER_VALIDATE_REGEXP

Valide une valeur à l’aide d’une expression régulière compatible PERL. L’expression régulière à utiliser est spécifiée grâce à l’option regexp.

FILTER_VALIDATE_EMAIL

Valide une valeur en tant qu’adresse électronique. 

FILTER_SANITIZE_STRING

images/logoversion8.png

Supprime les balises contenues dans une chaîne et encode les caractères et ". Plusieurs indicateurs sont disponibles pour supprimer ou encoder des caractères supplémentaires (voir ci-dessous). Déprécié à partir de la version 8.1 (à la place, utiliser la fonction htmlspecialchars présentée précédemment).

FILTER_SANITIZE_SPECIAL_CHARS

Encode en HTML les caractères , ", <, > et & ainsi que tous les caractères de code ASCII inférieur à 32. Plusieurs indicateurs sont disponibles pour supprimer...

Aller sur une autre page

Dans le traitement effectué par un script PHP, il peut être nécessaire d’afficher une autre page.

Le cas peut se produire par exemple à la fin du traitement d’un formulaire, la situation pouvant varier selon que le formulaire est traité par le script qui l’affiche ou par un script indépendant.

Variantes possibles

images/07RI32A.PNG

Rediriger l’utilisateur vers une autre page en cours de script est possible en utilisant la fonction header qui permet d’envoyer des en-têtes HTTP avec la page HTML (cf. chapitre Utiliser les fonctions PHP - Manipuler les en-têtes HTTP).

Nous allons utiliser l’en-tête location qui redirige la requête vers une autre adresse.

Syntaxe de la directive location

location: URL absolue ou relative 

Syntaxe avec la fonction header

header('location: URL absolue ou relative') 

Exemples

// Redirection vers un script PHP situé au même niveau. 
header('location: erreur.php'); 
// Redirection vers une page HTML située à un sous-niveau. 
header('location: ./erreur/saisie.htm'); 
// Redirection vers un autre site. 
header('location: http://www.olivier-heurtel.fr'); 

Le protocole HTTP 1.1 requiert une URL absolue dans la directive location. Pour cela, vous pouvez utiliser les variables globales $_SERVER[’HTTP_HOST’] et $_SERVER[’PHP_SELF’] (cf. chapitre Annexe - section Variables PHP prédéfinies).

Exemple

<?php 
$url_relative = 'erreur.php'; 
echo '$url_relative = ',$url_relative,'<br />'; 
echo '$_SERVER[\'HTTP_HOST\'] = ', 
      $_SERVER['HTTP_HOST'],'<br />'; 
echo '$_SERVER[\'PHP_SELF\'] = ', 
      $_SERVER['PHP_SELF'],'<br />'; 
echo 'dirname($_SERVER[\'PHP_SELF\']) = ', 
      dirname($_SERVER['PHP_SELF']),'<br />'; 
$url_absolue = 'http://' . $_SERVER['HTTP_HOST'] . 
               rtrim(dirname($_SERVER['PHP_SELF']), '/\\') . 
               '/' . $url_relative; 
echo '$url_absolue = ',$url_absolue,'<br...

Échanger un fichier entre le client et le serveur

1. Vue d’ensemble

Certains sites peuvent proposer aux utilisateurs de transférer des documents de leur poste vers le serveur web : déposer un CV sur un site (site de recherche d’emploi), mettre une pièce jointe dans un message (site de messagerie) ou simplement stocker le document sur le serveur (site de stockage).

Dans la terminologie anglo-saxonne, cette fonctionnalité s’appelle le "file upload".

Inversement, beaucoup de sites permettent aux utilisateurs de télécharger ("download") des documents du serveur web vers leur poste.

Ces deux fonctionnalités sont des applications particulières des techniques présentées dans ce chapitre.

2. Envoyer un fichier depuis le client (upload)

Cette fonctionnalité, très simple à mettre en œuvre en PHP, nécessite deux opérations :

  • dans un formulaire, proposer une zone permettant à l’utilisateur de désigner l’emplacement du fichier sur son poste.

  • dans le script de traitement du formulaire, récupérer le fichier envoyé par l’utilisateur et en faire quelque chose.

Dans la première partie de ce chapitre, nous avons vu la possibilité de mettre dans un formulaire une zone permettant d’indiquer l’emplacement d’un fichier sur son poste (type="file") :

Mettre une zone de ce type n’est pas suffisant. Pour provoquer le transfert du fichier, il suffit d’ajouter l’attribut enctype="multipart/form-data" dans la balise <form> :

<form action="saisie.php" method="post"  
    enctype="multipart/form-data"> 

Cette technique ne fonctionne qu’avec les formulaires qui utilisent la méthode POST.

En complément, il est possible d’ajouter une zone cachée dans le formulaire afin de limiter la taille des fichiers qui peuvent être envoyés vers le serveur. Cette zone cachée, obligatoirement située avant la zone de type file, doit s’appeler MAX_FILE_SIZE (attribut name) et préciser la taille maximum en octets dans l’attribut value :

Exemple de zone cachée pour limiter la taille des fichiers à 10 ko

<input type="hidden" name="MAX_FILE_SIZE"...