4 astuces pour améliorer le traitement de vos formulaires

Lorsque vous validez un formulaire, toutes les informations que vous avez remplies vont être incorporées dans une requête HTTP. Le format de ces données va dépendre de la structure de votre HTML. De l’autre côté d’internet, le code pour traiter la soumission d’un formulaire va fortement dépendre du contenu des requêtes HTTP. Nous allons voir quatre petites astuces HTML qui vont vous permettre d’avoir un code serveur plus propre ou plus sûr.

Astuce n°0 : Des échanges sécurisés

Ce n’est pas vraiment une astuce. C’est l’exemple le plus simple pour comprendre comment votre code HTML peut influencer le format de vos requêtes HTTP.

La balise <form> a un attribut method qui peut prendre deux valeurs : soit get, soit post. Ce paramètre indique quelle méthode du protocole HTTP sera utilisée. Si l’attribut n’est pas renseigné, votre formulaire utilisera la méthode GET.

Le principal avantage de la méthode POST est que les données du formulaire ne seront pas sauvegardées dans l’historique du navigateur. Il est donc vivement conseillé d’utiliser cette méthode pour les formulaires de connexion pour ne pas afficher le mot de passe en clair dans la barre d’adresse. Il est également conseillé de l’utiliser pour les formulaires d’ajout, de modification ou de suppression de données.

La méthode GET sera à privilégier pour les pages qui peuvent être gardées en favoris. Il est donc conseillé de l’utiliser pour les formulaires de recherches, par exemple. En effet, les paramètres soumis via la méthode GET apparaissent dans la barre d’adresse.

Astuce n°1 : Des déclencheurs explicites

Astuce : Vous pouvez donner un nom et une valeur à vos boutons.

Détails : Cette astuce vous permettra d’identifier facilement si un formulaire a été soumis ou non et ainsi déclencher le traitement de vos formulaires. Cela vous permettra aussi de pouvoir avoir facilement plusieurs actions sur un même formulaire.

Avantage : Pour les développeurs côté serveur, une même page sert souvent à délivrer et à traiter le formulaire. Il est donc important pour eux de savoir si le formulaire a été soumis à validation ou non. Tester la valeur du bouton leur permet d’avoir un test simple et lisible.

Exemple :

Code HTML :

<form method="post">
    <button type="submit" name="action" value="duplicate">Dupliquer</button>
    <button type="submit" name="action" value="delete">Supprimer</button>
</form>

Code PHP simplifié :

// Déclencheur : Le bouton "Supprimer" a été pressé
if (isset($_POST["action"]) && $_POST["action"] === "delete") {
    // Alors on traite le formulaire de suppression
    // Déclencheur : Le bouton "Dupliquer" a été pressé
} else if (isset($_POST["action"]) && $_POST["action"] === "duplicate") {
    // Alors on traite le formulaire de duplication
} else {
    // Sinon pas de traitement
}

À noter qu’avec les nouveaux attributs HTML5 formaction et formmethod, vous pouvez définir une URL d’action différente sur les boutons d’un même formulaire.

Astuce n°2 : Des valeurs explicites

Astuce : Vous pouvez mettre des valeurs sur vos cases à cocher.

Détails : Les champs de type checkbox ont par défaut une valeur à on. Cette astuce vous permet d’envoyer la valeur de votre choix.

Avantage : Avoir une valeur à tester avec un nom ou avec un identifiant, permet aux développeurs côté serveur d’avoir un code avec plus de sens. Le code pourra donc être compris, sans avoir besoin de lire le code HTML.

Exemple :

Code HTML :

<form method="post">
    <input type="checkbox" name="newsletter" value="weekly" />
    <button type="submit" name="action" value="validate">Valider</button>
</form>

Code PHP simplifié :

// Déclencheur
if (isset($_POST["action"]) && $_POST["action"] === "validate") {
    // Traitement
    if (isset($_POST["newsletter"]) && $_POST["newsletter"] === "weekly") {
        // Case cochée
    } else {
        // Case non cochée ou erreur
    }
}

Astuce n°3 : Des validations facilitées

Astuce : Vous pouvez mettre une valeur par défaut grâce aux champs cachés sur vos cases à cocher, vos boutons radios et sélections.

Détails : Il suffit pour cela de placer un champ caché avec le même nom avant le champ sur lequel vous souhaitez placer une valeur de secours.

Pour comprendre comment cela fonctionne :

  1. Les champs de type hidden envoient leur valeur quoi qu’il arrive.
  2. Les champs de type checkbox, radio et select ne renvoient pas de valeur, si aucune valeur n’est marquée comme checked ou selected.
  3. Si une valeur est sélectionnée, elle sera envoyée également.
  4. Le champ qui apparaîtra en deuxième dans le DOM sera en deuxième dans la requête HTTP et surchargera la première valeur à l’interprétation par le serveur.

Avantage : Pour savoir si une case n’a pas été cochée, il faut tester qu’il n’y ait pas de valeur envoyée. En général, les développeurs back n’aiment pas trop cela, car ils ne peuvent pas différencier un cas d’erreur (donnée corrompue) d’une case non cochée. Avec cette astuce, ils peuvent séparer la validation du formulaire et son traitement.

Exemple :

Code HTML :

<form method="post">
    <input type="hidden" name="newsletter" value="never" />
    <input type="checkbox" name="newsletter" value="weekly" />
    <button type="submit" name="action" value="validate">Valider</button>
</form>

Code PHP simplifié :

// Déclencheur
if (isset($_POST["action"]) && $_POST["action"] === "validate") {
    // Validation
    if (isset($_POST["newsletter"])) {
        // Traitement
        if ($_POST["newsletter"] === "weekly") {
            // Case cochée
        } else {
            // Case non cochée
        }
    } else {
        // Erreur
    }
}

Astuce n°4 : Des clés organisées

Astuce : Vous pouvez créer des tableaux de données sur vos champs de formulaires.

Détails : On peut créer des clés de tableau profondes à l’aide des crochets « [«  et  »] ». Attention cette technique n’est pas présente dans les RFC, notamment celle sur les URI RFC3986. Sa gestion dépendra donc du langage serveur ou du framework utilisé. Pensez donc à vérifier son implémentation avant.

Avantage : Cette astuce vous permet d’organiser les données de votre requête HTTP. Pour les long formulaires, cela vous permet également de grouper et d’éviter les chevauchements entre les clés. Les développeurs côté serveur peuvent récupérer les listes de données plus rapidement et produire un code plus lisible avec des données structurées.

Exemple :

Code HTML pour une liste :

<form method="post">
    <input type="checkbox" name="hobbies" value="" />
    <input type="checkbox" name="hobbies[]" value="sport" />
    <input type="checkbox" name="hobbies[]" value="web" />
    <input type="checkbox" name="hobbies[]" value="food" />
    <button type="submit" name="action" value="validate">Valider</button>
</form>

Code PHP simplifié :

// Déclencheur
if (isset($_POST["action"]) && $_POST["action"] === "validate") {
    // Validation
    if (isset($_POST["hobbies"])) {
        // Traitement
        if (is_array($_POST["hobbies"])) {
            // Tableau de loisirs sélectionnés
        } else {
            // Pas de loisirs sélectionnés
        }
    }
}

Code HTML pour un tableau :

<form method="post">
    <input type="text" name="user[name]" />
    <input type="text" name="user[lastname]" />
    <input type="password" name="password[original]" />
    <input type="password" name="password[confirm]" />
    <button type="submit" name="action" value="register">S’inscrire</button>
</form>

Conclusion

Toutes ces astuces ne sont pas à utiliser sur tous les projets, mais il est important de savoir qu’elles existent. Je les ai, par exemple, beaucoup utilisées sur un projet d’interface d’administration. Avec quelques modifications sur mes formulaires HTML, j’ai réussi à améliorer la robustesse du code PHP.

Une preuve de plus que les développeurs côté client et serveur ont tout intérêt à travailler ensemble et échanger tout au long des projets.

13 commentaires sur cet article

  1. Maxime Siméon, le 4 décembre 2013 à 11:42

    Intéressant et accessible au simple web designer. Merci Thomas pour ces astuces

  2. Wan, le 4 décembre 2013 à 15:57

    Pas mal, merci à l'auteur ! En particulier les astuces sur les checkbox sont bien trouvées, je prends note.

  3. ForgetTheNorm, le 4 décembre 2013 à 18:20

    L'article est intéressant. J'aurai une critique à faire sur l'explication GET/POST, qui pour moi ne se résume pas à "affiché ou non dans l'historique", mais plutôt respectivement une "récupération" et une "action" sur une entité.

  4. neemzy, le 4 décembre 2013 à 21:29

    Article intéressant ; de mémoire les helpers de génération de formulaires pour Rails emploient nativement l'astuce de l'input[hidden] qui sert de valeur par défaut. Je l'avais oubliée celle-là d'ailleurs, merci !

    (Au fait, pas très sûr de cette ligne :

    if (isset($_POST["newsletter"]) && isset($_POST["newsletter"]) === "weekly") {

    le deuxième isset est de trop, non ?)

  5. RastaPopoulos, le 5 décembre 2013 à 9:42

    En PHP "isset" ne renvoie QUE "true" ou "false". Donc dans cet article, tous les isset($variable) === "valeur" sont faux.

    Pour tester la valeur… on teste la valeur, pas le isset(). :D

  6. tzi, le 5 décembre 2013 à 9:55

    @neemzy Bien vu pour les isset() de trop. Merci :) ce sera corrigé !

    @ForgetTheNorm Je ne suis pas sûr d'avoir compris. Est-ce que "ajout, modification et suppression" représente les actions, et la recherche la récupération.

    @Maxime, Wan Merci :)

  7. Julien, le 5 décembre 2013 à 12:51

    @tzi par rapport à ce qu'a dit @ForgetTheNorm : il y a une notion de sécurité sous-jacente : https://fr.wikipedia.org/wiki/Cross-site_request_forgery

    Cette attaque est utilisable dès qu'un script coté serveur autorise une action via un GET, quelle que soit la vérification des droits de l'utilisateur faite avant.

  8. ForgetTheNorm, le 5 décembre 2013 à 15:07

    @tzi Un ajout, une modification ou une suppression sont effectivement des actions, et doivent être demandées par un POST (ou un PUT/DELETE si tu utilises un framework RESTful). La visualisation d'une page, l'obtention d'une ressource se fait via un GET.

    @Julien Merci pour ton lien très intéressant, je ne connaissais pas cette attaque.

  9. Nicolas Casel, le 6 décembre 2013 à 7:37

    Merci pour ce mini-tutoriel : concis, clair, bien rédigé :-)

    Remarque sur une condition : il faut écrire : $_POST["value"]==="validate" Et non pas ["action"] ... ?

  10. tzi, le 9 décembre 2013 à 14:00

    @ForgetTheNorm, @Julien: Merci pour les précisions sur le sujet.

    @NicolasCasel: Si tu écris myLabel : 1/ tu récupères une requête HTTP du type "myKey=myValue" 2/ Ce qui fait que tu testes "$_POST['myKey'] === myValue". Donc sauf erreur de ma part, c'est bien "$_POST['action']==='validate'"

  11. Bartdude, le 30 décembre 2014 à 9:31

    Je n'ai pas accès là tout de suite à une machine pour tester ça, mais le traitement des champs de formulaire ayant le même nom n'est-il pas une question de technologie du serveur ? Pour ma part j'ai toujours été persuadé pour l'avoir constaté par le passé que si plusieurs champs avaient le même nom, on se retrouvait côté serveur avec une seule variable où les valeurs des champs étaient concaténées, séparées par une virgule. Ce comportement pourrait d'ailleur expliquer la relativement simple mise en place des "clés organisées" dont tu parles ici aussi.

  12. Bartdude, le 30 décembre 2014 à 9:33

    Ah oui, j'ai oublié d'ajouter que de 0 à 4 ca fait quand-même 5 astuces, pourquoi ce titre donc ? :-)

  13. Sophie ~ GSA, le 2 septembre 2015 à 22:44

    Et quand on utilise wordpress, comment ça se passe ?

Il n’est plus possible de laisser un commentaire sur les articles mais la discussion continue sur les réseaux sociaux :