Traiter et valider proprement un formulaire PHP

Le formulaire sur le web est le moyen le plus utilisé pour transmettre et/ou interagir avec [les données] utilisateurs. Cependant, PHP étant un langage permissif, les débutants en ce langage commettent des graves erreurs quant au traitement et la validation de formulaire.

Traiter le formulaire PHP

Même si on peut valider les données avec HTML5 sans JavaScript, Never trust user input reste toujours l’expression utilisée pour dire simplement qu’il faut toujours valider les données provenant des utilisateurs hormis les traiter.

Si vous demandez un numéro de téléphone, vous devriez vous assurer à 100% que la donnée fournie correspond ou est un numéro de téléphone avant de l’enregistrer ou l’utiliser.

La logique dans la validation d’un formulaire coté serveur  reste simple :

  1. Récupération des données utilisateur
  2. Vérification des données utilisateurs
  3. Si les données sont valides, on effectue l’opération prévue sur celles-ci
  4. Si non, on le renvoie dans la page de formulaire avec l’affichage de message d’erreurs.

La plus part du temps, ce qui rend difficile tout ce processus pour un développeur PHP débutant, c’est le manque d’une structure homogène et cohérente de validation de ces données.

Découvrons dans la suite comment traiter et valider proprement un formulaire avec PHP tout en se servant de la programmation défensive d’abord en scratch pour mieux comprendre comment ça marche et après je vous montrerai les librairies à utiliser pour gagner en productivité.

Exemple de guide du traitement et validation de formulaire PHP

Pour ce tuto, nous allons valider un formulaire qu’on rencontre fréquemment sur la toile, le formulaire d’un commentaire. Celui-ci a comme champ :

  • Nom : Qui ne peut pas être vide, peut contenir des chiffres et des lettres mais pas caractères spéciaux et est obligatoire.
  • Email : Qui est obligatoire et doit correspondre à un email valide
  • Url : Qui est facultatif mais quand c’est renseigné, il doit correspondre à un URL valide
  • Message : Qui ne peut être vide et est donc obligatoire
POUR VOUS
Laravel : Définir la langue des dates Carbon

Pour chaque invalidité d’un champ, le pourquoi de cette invalidité doit être mentionnée.

Formulaire en HTML

Je valide mon formulaire dans le même fichier que mon fichier HTML juste avant la déclaration de Doctype pour rester simple. Voici pour l’instant juste le formulaire

<?php
//Mon code PHP sera juste là
?>
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Exemple de ton code</title>
	<style>
		.error
		{
			color: red;
		}
	</style>
</head>
<body>
	<form method="post" action="./">
		<?php if(!empty($errors)): ?>
			<legend>Les erreurs ont été trouvées</legend>
		<?php endif; ?>
		<p>
			<label>Nom (*) </label>
			<input type="text" name="nom" />
			<?php echo show_error('nom') ?>
		</p>
		<p>
			<label>Email (*)</label>
			<input type="email" name="email" />
			<?php echo show_error('email') ?>
		</p>
		<p>
			<label>Site web</label>
			<input type="text" name="url" />
			<?php echo show_error('url') ?>
		</p>
		<p>
			<label>Message (*) </label>
			<textarea name="message"></textarea>
			<?php echo show_error('message') ?>
		</p>
		<input type="submit" value="Soumettre le formulaire">
	</form>
</body>
</html>

Rien de bien compliquer ici si ce n’est que l’utilisation de la fonction show_error() que je veux expliquer quand je veux la créer. Pour l’instant, ce code va bien générer une erreur car la fonction show_error n’est pas encore définie.

Traitement PHP

Je veux placer mon script PHP juste avant la déclaration de DOCTYPE. La logique de mon traitement est tout de même aussi simple.

J’ai une variable de type array $errors que j’aurais à remplir avec comme clé, l’attribut name de chaque champ (input) et comme valeur, le message d’erreur à chaque fois qu’il y en aura. (Je veux revenir).

D’abord je crée la fonction show_error() qu’on a vu précédemment qui me permettra de formater et afficher les messages d’erreur.

La fonction prend comme argument la valeur de l’attribut name de chaque input. Cela me permet de récupérer directement le message d’erreur depuis la variable $errors et de l’afficher.

/**
* Affiche les erreurs rencontrées
* @param $key 
* @return String
*/
function show_error($key)
{
    global $errors; //Récupère la variable $errors dans la portée globale
    return !empty($errors[$key]) ? '<span class="error">'. $errors[$key] .'</span>' : ''; 
}

Ma fonction n’est pas si compliqué que ça, une condition ternaire pour ne rien afficher si la clé $key n’existe pas dans le tableau $errors.

Et quand $key existe bien sur $errors, c’est qu’il y a un message d’erreur à afficher, donc ce que certains champs du formulaire ne sont pas valide.

POUR VOUS
La portée d'une variable en PHP

Validation formulaire PHP

Rappelez-vous, on va remplir la variable $errors à chaque fois qu’on va effectuer une validation d’un input par $errors[$key] = 'Message d\'erreur'$key est l’attribut $name de l’input.

Allez ! Le code dira plus mieux ! Je commence la validation

if(!empty($_POST))
{
   if(empty($_POST['nom'])) {
      $errors['nom'] = "Le nom ne peut être vide";
   }
   if(!preg_match('/^([a-z0-9] )*$/i', $_POST['nom'])){
      $errors['nom'] = "Le nom doit contenir que les lettres et les chiffres";
   }
   if(empty($_POST['email']) OR !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){
      $errors['email'] = "L'email entré n'est pas valide";
   }
   if(!empty($_POST['url']) && !filter_var($_POST['url'], FILTER_VALIDATE_URL)){
      $errors['url'] = "L'URL entré n'est pas valide";
   }
   if(empty($_POST['message'])){
      $errors['message'] = 'Le message ne peut être vide';
   }
}

Rien de bien compliqué non plus ici, juste des simples conditions mais au passage, j’ai utilisé la fonction filter_var pour valider l’URL et l’email et preg_match à travers une expression régulière.

Et au final, je peux savoir facilement si les données sont valides qu’en vérifiant si la variable $errors est vide et je peux effectuer l’opération prévue pour celles-ci.

if(empty($errors))
{
   echo 'Toutes les données sont valides ';
   // Enregistrement dans la base de données
}

[Télécharger le code complet]

Allez plus loin

La manière qu’on a procédé est très loin d’être plus mieux. Voici les améliorations possibles que vous pouvez faire

  • Pré emplir le formulaire en cas d’erreur avec les données précédemment entrée.
  • Respecter l’architecture MVC, en subdivisant le formulaire avec un fichier Controller et une Vue.
    Et si l’opération à effectuer après validation est de stocker ces données dans la base de données, disposez aussi d’un modèle, un fichier où vous allez déclarer les fonctions qui vont exécuter toutes les requêtes SQL pour la table X, que vous auriez à appeler depuis le Controller.
POUR VOUS
PHPStorm un environnement de développement intégré WEB pour le pro

Utilisation des librairies

Si vous avez compris la logique de validation d’un formulaire, inutile de gaspiller beaucoup de temps à écrire les contraintes des données, la grande communauté de PHP a fait quasi tout ce qu’il faut pour valider rapidement et efficacement les données issues d’un formulaire à travers différentes librairies

GUMP

Gump est une librairie très pratique pour valider les données issues d’un formulaire. Il peut aussi être chargé via composer. Voici une utilisation très basique (notre exemple précédent)

require "gump.class.php";

$is_valid = GUMP::is_valid($_POST, array(
	'nom' => 'required|alpha_numeric',
	'email' => 'required|valid_email',
        'url' => 'valid_url',
        'message' => 'required'
));

if($is_valid === true) {
  echo "Toutes les données sont valides";
} else {
   print_r($is_valid);
}

VALITRON

Valitron est aussi une librairie de validation des données PHP qui a l’ère d’être très pratique aussi. En quelque ligne de code, vous validez beaucoup de données.

Finalement, chacun cultive sa manière de faire les choses, si vous n’avez pas encore une manière stricte de valider vos formulaire sans doute celle ci, mais si vous en avez déjà, faites le pour et le contre.

Ajouter un commentaire