Formation PUB010 : PHP, 2018 La validation d'un formulaire Web

Valider un formulaire côté serveur avec PHP


La validation d'un formulaire Web est une tâche complexe. Il faut en effet s'assurer que les données entrées par l'usager correspondent au format attendu, qu'elles soient valables et qu'elles ne compromettent pas la sécurité du site Web.

Normalement, une fois que l'usager a cliqué sur le bouton de soumission, les données entrées devraient être valides puisque la validation a déjà été effectuée côté client. Cependant, comme cette validation peut être désactivée, il est absolument nécessaire de refaire la validation côté serveur.

Voici les étapes permettant de bien valider les données d'un formulaire avec PHP.

▼Publicité

Valider le format attendu

Si au moins une erreur est détectée

Si au moins une erreur est détectée, il faut afficher un message d'erreur puis permettre à l'usager de corriger la situation.

Le message doit indiquer clairement chacune des erreurs rencontrées.

Si aucune erreur n'est détectée

Les données correspondent toutes au format attendu. Parfait ! Il reste cependant des vérifications à faire avant de poursuivre le traitement du formulaire.

Valider que les données sont valables

Une donnée sera valable si elle correspond à une valeur acceptée. Pour vous assurer que les données soient valables :

  • Pour chaque information numérique, s'assurer que la valeur entrée est effectivement numérique. On peut également procéder simplement à une conversion de type.
  • Les informations choisies dans une liste déroulante pourraient avoir été falsifiées par un usager malveillant. Il faut donc s'assurer que la valeur qui sera utilisée comme clé étrangère correspondent bel et bien à un enregistrement dans la table qui contient la clé primaire associée.

Enregistrer les données sans compromettre la sécurité

Avant de procéder à l'enregistrement des données, il est important de sécuriser le code afin de limiter les risques que les informations entrées par l'usager soient la source d'une attaque (en anglais, on dira « sanitize input »). Ainsi, une fois que nous nous sommes assurés que les données correspondent au format attendu et qu'elles sont valables, il faut les désinfecter. La désinfection consiste notamment à s'assurer qu'aucune balise <script> et aucun apostrophe ou guillemet ne pourra causer de comportement inattendu.

Il est absolument nécessaire de travailler avec les requêtes préparées pour assurer que les données soient correctement désinfectées avant l'enregistrement.

Les requêtes préparées se chargeront d'effectuer certaines opérations de désinfection que les développeurs effectuaient autrefois de façon manuelle (ex : addslashes()) et iront même plus loin pour augmenter la sécurité.

Et, bien important, un message devra indiquer à l'usager si l'opération a été réussie ou non.

Certaines de ces étapes seront couvertes dès maintenant alors que d'autres seront vues un peu plus tard pour vous permettre de souffler un peu !

Gardez cette fiche à portée de la main car toutes les étapes y sont obligatoires pour assurer que le formulaire fonctionne bien.

Un exemple vaut mille mots

Voici un algorithme qui vous aidera à ne rien oublier lorsque vous traitez un formulaire. Cet algorithme est bien sûr perfectible. Libre à vous de l'utiliser, de le perfectionner ou de développer votre propre algorithme.

PHP

// *** protection XSS ******************************************************************

 

(la technique de protection sera vue plus loin...)

 

// *** initialisation des variables pour clarifier le code *****************************

 

$modele = $_POST['modele'];

$description = $_POST['description'];

$annee = $_POST['annee'];

...

 

// *** validations côté serveur ********************************************************

 

$message = '';

 

// format attendu : champs obligatoires
if ('' == $modele) {

    $message .= 'Le modèle est requis.<br \>';

}

 

if ('' == $description) {

    $message .= 'La description est requise.<br \>';

}

 

// format attendu : longueur des champs

if (!empty($annee) && 4 != mb_strlen($annee)) {

    $message .= 'L\'année, lorsque fournie, doit comporter exactement 4 caractères.<br \>';

}

 

if (mb_strlen($description) > 100) {

    $message .= 'La description ne doit pas comporter plus de 100 caractères.<br \>';

}

 

// format attendu : courriel

if (!filter_var( $courriel, FILTER_VALIDATE_EMAIL)) {
    $message .= 'Le courriel n\'est pas valide. Il doit être au format unnom@undomaine.uneextension.<br /> &nbsp; &nbsp; Il doit comporter un seul caractère @.<br /> &nbsp; &nbsp; Ce caractère doit être suivi d\'un nom de domaine qui contient au moins un point puis une extension.<br /> &nbsp; &nbsp; Les caractères spéciaux ne sont pas acceptés.<br \>';
}

 

// format attendu : code postal canadien
if(!preg_match("/^[ABCEGHJKLMNPRSTVXYabceghjklmnprstvxy][0-9][ABCEGHJKLMNPRSTVWXYZabceghjklmnprstvwxyz] ?[0-9][ABCEGHJKLMNPRSTVWXYZabceghjklmnprstvwxyz][0-9]$/i",$sujet)) {
    $message .= 'Le code postal n\'est pas valide. Il doit être au format A9A 9A9.<br /> &nbsp; &nbsp; Les lettres D, F, I, O, Q et U ne sont pas acceptées.<br /> &nbsp; &nbsp; Les lettres W et Z sont acceptées mais pas en première position.<br \>';
}
 

// données valables : champs numériques

if (!empty($annee) && !ctype_digit($annee)) {

    $message .= 'L\'année, lorsque fournie, doit être un entier.<br \>';

}

 

//données valables : valeur décimale

if (!empty($rang)) {

    // si on n'a pas besoin de vérifier la valeur maximale, omettre le else

    if (!is_numeric($annee)) {

        $message .= 'Le rang, lorsque fourni, doit être un nombre qui peut comporter une partie décimale.<br \>';

    }

    else {

        // si on vérifie avec l'expression régulière, pas besoin de vérifier le is_numeric()

        if (!preg_match("/^[0-9]{1,3}([.,][0-9]{1,2})?$/", $rang)) {

            $message .= "Le rang, lorsque fourni, doit être au format 999.99";

        }

    }

}

 

// données valables : clés étrangères

$requete = "...";

...    // attention : pour être sécuritaire, utiliser une requête préparée

if ($stmt->num_rows == 0) {

    $message = 'Le modèle choisi n\'est pas valide.';

}

 

if ('' != $message) {

 

    // *** affichage du message ********************************************************

    echo "<div class='messageerreur'>$message</div>";

 

    // *** réaffichage du formulaire avec les données qui y ont été saisies ************

    ...

 

} else {

 

    // *** enregistrement *************************************************************

    ... 

}

Dernière révision le 14 avril 2020
Merci de partager !

Site fièrement hébergé chez A2 Hosting.

Soumettre