Accueil > Partage de connaissances > Guides techniques > Contrôler les variables PHP issues d’un (...)
 Version imprimable

Guides techniques
Programmation PHP
Contrôler les variables PHP issues d’un formulaire HTML

Le script PHP chargé du traitement d’un formulaire HTML peut exiger la présence d’un champ, même vide : comment faire ce contrôle ? De plus, PHP peut avoir été configuré pour ne tolérer aucun écart de programmation (mode "strict", ou équivalent) : dans ce cas, il conviendra de vérifier systématiquement l’existence d’un champ avant d’en copier l’éventuel contenu.

Première publication le 10 juillet 2004
Date de dernière mise en ligne : samedi 12 septembre 2009, par Richard BONMARIN

Le contenu de chaque champ défini dans le formulaire associé au script PHP est porté dans l’un des deux tableaux spéciaux gérés par PHP ; ces tableaux se nomment "$_POST[]" pour les variables HTML envoyées par méthode POST, et "$_GET[]" pour les variables HTML envoyées par méthode GET ou associées à l’URL du formulaire.

Le contrôle d’existence du champ consiste tout simplement à vérifier qu’il existe bien une occurrence portant le nom du champ HTML dans le bon tableau...

Exemple :
if (isset($_POST["champ01"])) {
        $HV_champ01 = $_POST["champ01"];
} else {
        $HV_champ01 = "";;
}
La même chose, en plus compact :
$HV_champ01 = (isset($_POST["champ01"]) ? $_POST["champ01"] : "");

Contrôle syntaxique d’un champ

La première précaution à prendre pour éviter toute tentative malveillante consiste à vérifier sans délai que les données attendues sont bien là et sous une forme valide. L’exemple ci-dessus montre comment vérifier l’existence d’un champ : reste à s’assurer de sa cohérence !

La validité d’un champ dépend de sa nature : on contrôlera différemment une date, une valeur issue d’une liste de choix ou un texte libre.

La longueur d’un champ est probablement la première chose à vérifier. Mais, me direz-vous, pourquoi effectuer ce contrôle alors que le formulaire HTML le fait déjà via le paramètre MAXLENGTH ? Tout simplement parce que rien n’empêche une personne mal intentionnée de copier votre formulaire original, modifier la copie en supprimant les paramètres gênants et introduire ce qu’on appelle du code malicieux dont le but est de nuire au bon fonctionnement de votre application ou d’en extraire des informations sensibles. C’est comme cela qu’une grande société américaine a délivré, à son corps défendant, les numéros des cartes bancaires de ses clients !

Voici donc quelques moyens de contrôle basiques : charge à vous de les adapter et les compléter selon vos besoins.

Contrôle d’une longueur fixe
if (strlen($HV_champ99) != 10) exit("Longueur de champ99 invalide.");
Contrôle d’une longueur variable, avec mini et maxi
if ((strlen($HV_champ99) < 3)
AND (strlen($HV_champ99) > 15)) {
  exit("Longueur de champ99 invalide.");
}
Contrôle de numéricité
if (!is_numeric($HV_champ99)) exit("champ99 non numérique.");
Contrôle de validité d’une date
if (strtotime($HV_champ99) == -1) exit("champ99 n'est pas une date valide.");

Remarque : Reportez-vous à l’article traitant de la gestion des dates pour de plus amples informations à ce sujet.

Contrôle d’une structure fixe

Si un champ doit se conformer à une structure prédéterminée, assurez-vous que cette structure est respectée. Pour cela, vous pouvez soit faire un contrôle sommaire (vérifier la position d’un caractère constant dans la structure : un tiret en 6ème position, par exemple), soit exploiter les "expressions régulières" pour une analyse plus sophistiquée.

Un exemple concret

Supposons que la clé d’accès à un enregistrement de votre base de données doit impérativement respecter la structure "XXXaa-qqq-nn", où :
- XXX prend 2 valeurs possibles : "ACT" ou "REQ"
- aa représente l’année de création de l’enregistrement sur 2 caractères
- qqq est le quantième de la date de création ; il prend donc une valeur comprise entre 001 et 366 inclus
- nn est un numéro d’ordre allant de 01 à 99 inclus
- deux tirets en position 6 et 10 facilitent la lisibilité de l’ensemble

Les règles de structure se vérifient facilement par une succession de contrôles unitaires :

Contrôles unitaires appliqués à une variable nommée ’$HV_id’
if (strlen($HV_id) != 12) {
        exit("Structure invalide pour l'identifiant '$HV_id'");
}
if ( (substr($HV_id,0,3) != "ACT")
        AND (substr($HV_id,0,3) != "REQ")) {
        exit("Structure invalide pour l'identifiant '$HV_id'");
}
if ( !is_numeric(substr($HV_id,3,2)) ) {
        exit("Structure invalide pour l'identifiant '$HV_id'");
}
if ( substr($HV_id,5,1) != "-" ) {
        exit("Structure invalide pour l'identifiant '$HV_id'");
}
if ( (!is_numeric(substr($HV_id,6,3)))
        OR (substr($HV_id,6,3) < 1)
        OR (substr($HV_id,6,3) > 366) ) {
        exit("Structure invalide pour l'identifiant '$HV_id'");
}
if ( substr($HV_id,9,1) != "-" ) {
        exit("Structure invalide pour l'identifiant '$HV_id'");
}
if ( (!is_numeric(substr($HV_id,10,2)))
        OR (substr($HV_id,10,2) < 1) ) {
        exit("Structure invalide pour l'identifiant '$HV_id'");
}

Les instructions ci-dessus offrent l’avantage d’être lisibles et simples à maintenir au prix d’un nombre relativement important de lignes de code.

Le recours aux Expressions Régulières permet, quant à lui, de réduire la taille du code au prix d’une plus grande complexité pour un résultat identique :

Contrôle par Expression Régulière d’une variable nommée ’$HV_id’
$patt = "/";        // prépa insensibilité à la case
$patt .= "(ACT|REQ)";   // 2 valeurs admises
$patt .= "(\d{2})-";        // 2 chiffres suivis d'un tiret
$patt .= "(\d{3})-";        // 3 chiffres suivis d'un tiret
$patt .= "(\d{2})";        // 2 chiffres
$patt .= "/i";        // insensible à la case
if ( !preg_match($patt,$HV_id) ) {
        exit("Structure invalide pour l'identifiant '$HV_id'");
}

Remarque : Restent à valider les valeurs possibles pour chaque élément ’aa’, ’qqq’ ou ’nn’.

Post-scriptum :

Seules vos habitudes de programmation vous feront pencher pour l’une ou l’autre forme de contrôle : à vous de choisir celle vous convenant le mieux, mais gardez à l’esprit que ces contrôles, même s’ils sont fastidieux, participeront à la protection de vos applications sensibles.


(Aucune contribution au forum)


 

© R. BONMARIN, 2003-2011