PHP - MySQL [Retour au menu]
Validation d'un formulaire d'inscription

Il est très fréquent de devoir créer un formulaire d'inscription ou le visiteur doit entrer ses noms, prénoms, adresse, etc. Mais avant d'aller plus avant, et de (par exemple) se précipiter sur la base de données MySQL pour y retranscrire les informations fournies, il est bien de vérifier certaines choses comme par exemple :

- N'a-t-il pas laissé des champs importants comme le nom ou le prénom vides ?
- Y a-t-il bien le caractère @ au sein de l'E-Mail fourni, et y a-t-il bien du texte avant et après, et y a-t-il bien un point dans l'adresse
- Le mot de passe fourni contient-il bien au moins 6 caractères, et n'est il pas égal au nom ou au prénom ?

etc.

Bien entendu, certaines informations sont totalement invérifiables, comme par exemple : La ville indiqueée existe-elle, le nom est-il fictif, etc.

Matériel Nécessaire

C'est parti !

La super-astuce que nous allons utiliser est l'envoi du formulaire inscription.php sur lui-même avec l'instruction :

<form method="post" action="inscription.php">

Imaginons un formulaire dans le fichier inscription.php avec seulement 2 champs : Le nom et le prénom à remplir :

<body>
  <form method="post" action="inscription.php">
    Votre nom : <input type="text" name="Nom">
    <br>
    Votre prénom : <input type="text" name="Prenom">
    <br>
    <input type="submit" name="Submit" value="Envoyer">
  </form>
</body>

Le fait d'envoyer les données dans le même fichier va permettre d'afficher les données envoyées, comme ceci :

<body>
  <?  
    echo $Nom;
    echo $Prenom;
  ?>

  <form method="post" action="inscription.php">
    Votre nom : <input type="text" name="Nom">
    <br>
    Votre prénom : <input type="text" name="Prenom">
    <br>

    <input type="submit" name="Submit" value="Envoyer">
  </form>
</body>

Donc, la première fois qu'on arrive sur ce formulaire, les variables Nom et Prenom sont forcément vides puisqu'elles n'ont pas encore été alimentées. PAR CONTRE, dès qu'on remplit les champs de formulaire et qu'on clique sur ENVOYER, alors, comme on revient à nouveau sur inscription.php, on va voir afficher le nom et le prénom de la personne qui vient de s'inscrire.

Une seule page pour l'inscription et la validation !

Ce qui fait qu'une seule et même page peut servir par exemple à soit afficher le formulaire d'inscription, soit simplement confirmer l'inscription. Que pensez-vous de ceci :

<body>
  <?
    if (($Nom <> "") && ($Prenom <> ""))
      {
      echo "Merci de vous être inscrit !";
      exit;
      }

  ?>
  <form method="post" action="inscription.php">
    Votre nom : <input type="text" name="Nom"> <br>
    Votre prénom : <input type="text" name="Prenom"><br>
    <input type="submit" name="Submit" value="Envoyer">
  </form>
</body>

Ce code nous emmène au coeur de notre solution : La ligne if (($Nom <> "") && ($Prenom <> "")) va directement regarder si le nom ET (&&) le prénom sont bien remplis. Si les deux sont bien remplis, alors, on affiche simplement Merci de vous être inscrit !, et exit; va simplement arrêter tout brusquement le chargement de la page, ce qui fait évidemment que le code HTML du formulaire sera purement et simplement évincé !

Et par contre, si l'un des deux champs n'est pas rempli, la condition if n'est pas remplie, la phrase "merci de vous être inscrits" ne sera pas affichée, et donc, le exit ne sera pas lu, et donc enfin, le code HTML du formulaire sera à nouveau affiché.

Ce qui fait que nous allons maintenant pouvoir gérer plus finement notre code : Bon, évidemment, plutôt que d'écrire bêtement "Merci de vous être inscrit", il va de soi qu'un code plus complet, comme par exemple l'écriture du nom et du prénom dans la base de données, suivi d'un lien hypertexte qui renvoie à une autre page, comme par exemple la page d'accueil du site qui va recevoir ce formulaire serait plus judicieux, mais tout ceci n'est pas le sujet de cette étude.

Nous allons plutôt rendre l'utilisateur attentif au fait que certains champs ne sont pas remplis : nous allons simplement écrire en rouge (#FF0000) que le Nom doit être renseigné, et nous allons réafficher le formulaire :

<body>
  <?
    if (($Nom <> "") && ($Prenom <> ""))
      {
      echo "Merci de vous être inscrit, " , $Prenom , " " , $Nom;
      exit;
      }
  ?>
  <form method="post" action="inscription.php">
    <?
      if ($Nom == "")
        {
        echo "<font color='#FF0000'>";
        echo "Le Nom DOIT être rempli :";
        echo "</font>";
        echo "<BR>";
        }
    ?>

    Votre nom : <input type="text" name="Nom"><br>
    Votre prénom : <input type="text" name="Prenom"><br>
    <input type="submit" name="EnvoyerDonnee" value="Envoyer">
  </form>
</body>

La partie en bleu, nous la connaissons bien, c'est dans le cas ou tout va bien : Les champs sont bien remplis, et on confirme l'inscription. La partie en rouge est justement cette nouvelle partie qui va nous dire que le nom n'est pas renseigné, et que donc il faut remédier à cet état de fait, et il va réafficher le formulaire comme avant.

Bon, très bien, mais... la première fois qu'il arrive sur ce formulaire, l'utilisateur se fait immédiatement remettre en place : en effet, la première fois qu'on arrive, le $Nom est bel et bien vide, et donc, le message en rouge va s'afficher... Pas très sympathique.

Utilisation du bouton d'envoi comme témoin de rechargement de la page

En fait, pour éviter l'affichage du message d'erreur lors du premier passage, il faut arriver à déterminer que l'utilisateur à déjà appuyé sur le bouton Envoyer. Eh bien, ce bouton Envoyer a lui même une valeur : <input type="submit" name="EnvoyerDonnee" value="Envoyer">. Et donc, implicitement, quand l'utilisateur va cliquer sur ce bouton, il va envoyer du même coup la variable EnvoyerDonnee qui va contenir bêtement la chaîne de caractère ... "Envoyer" ! (ce qui est écrit sur le bouton en fait).

Ce qui fait qu'en finalité, nous n'allons afficher notre message en rouge QUE si le Nom est vide ET QUE la variable EnvoyerDonnee N'EST *PAS* VIDE !, comme ceci :

<body>
  <?
    if (($Nom <> "") && ($Prenom <> ""))
      {
      echo "Merci de vous être inscrit, " , $Prenom , " " , $Nom;
      exit;
      }
  ?>
  <form method="post" action="inscription.php">
    <?
      if (($Nom == "") && ($EnvoyerDonnee <> ""))
        {
        echo "<font color='#FF0000'>";
        echo "Le Nom DOIT être rempli :";
        echo "</font>";
        echo "<BR>";
        }
    ?>
    Votre nom : <input type="text" name="Nom"><br>
    Votre prénom : <input type="text" name="Prenom"><br>
    <input type="submit" name="EnvoyerDonnee" value="Envoyer">
  </form>
</body>

Résumons-nous

Si Alors
C'est la première fois qu'on arrive sur le formulaire if (($Nom <> "") && ($Prenom <> "")) n'est pas vrai : Donc pas de confirmation d'inscription
if (($Nom == "") && ($EnvoyerDonnee <> "")) : Nom est bien vide, c'est vrai, mais EnvoyerDonnee est aussi vide, donc la condition est fausse, et donc le texte en rouge ne s'affiche pas !
On a cliqué sur Envoyer, et donc c'est au moins la 2ème fois qu'on arrive sur le formulaire

if (($Nom <> "") && ($Prenom <> "")) est peut être vrai : Si les 2 champs ont été renseignés, alors, la condition est vraie, et le message de confirmation d'inscription est affiché, et on sort de la page avec exit;

Si l'un des deux champs ou même les deux sont vides, alors la condition n'est plus vraie, et donc on affiche pas la confirmation et l'exit n'est pas exécuté. On continue l'affichage de la page

Et donc if (($Nom == "") && ($EnvoyerDonnee <> "")) : Si c'était le nom qui n'était pas renseigné, c'est donc que Nom == "", et donc on affiche le mesage en rouge
Et si par hasard on insiste et qu'on clique encore une fois sur Envoyer, et qu'on laisse encore une 2ème fois le Nom vide ? ça ne change rien à notre programmation : Le nom est toujours == "" et EnvoyerDonnee est toujours == "Envoyer", le messaghe en rouge revient inlassablement, même si on clique 10 fois de suite sur Envoyer.

Complétons maintenant notre code par la gestion du prénom et de l'E-Mail de la même manière. J'ai rajouté des commentaires pour clarifier le code (<!-- Gestion de tel champ: -->), et j'ai écrit les if sur une seule ligne pour éviter un code trop long (echo "<font color='#FF0000'> Tel champ DOIT être rempli :</font><BR>";) . N'oublions pas d'ajouter la vérification de l'E-Mail en tout début (&& ($EMail <> ""))

<body>
  <?
    if (($Nom <> "") && ($Prenom <> "") && ($EMail <> ""))
      {
      echo "Merci de vous être inscrit, " , $Prenom , " " , $Nom;
      exit;
      }
  ?>

  <form method="post" action="inscription.php">
    <!-- Gestion du nom : -->
    <?
      if (($Nom == "") && ($EnvoyerDonnee <> ""))
        echo "<font color='#FF0000'> Le Nom DOIT être rempli :</font><BR>";
    ?>
    Votre nom : <input type="text" name="Nom"> <br>


    <!-- Gestion du Prénom : -->
    <?
      if (($Prenom == "") && ($EnvoyerDonnee <> ""))
        echo "<font color='#FF0000'> Le prénom DOIT être rempli :</font><BR>";
    ?>
    Votre prénom : <input type="text" name="Prenom"> <br>

    <!-- Gestion de l'E-Mail : -->
    <?
      if (($EMail == "") && ($EnvoyerDonnee <> ""))
        echo "<font color='#FF0000'> L'E-Mail DOIT être rempli :</font><BR>";
    ?>
    Votre E-Mail : <input type="text" name="EMail"> <br>

    <input type="submit" name="EnvoyerDonnee" value="Envoyer">

  </form>
</body>

Ce code fonctionne parfaitement, et vous pouvez le tester ici.

Evitons à l'utilisateur de devoir entrer plusieurs fois les données correctes

Toutefois, il reste quelque chose de très très énervant pour l'utilisateur, c'est que s'il a correctement rempli son nom et son prénom, mais qu'il a oublié son E-Mail, la page va donc se recharger avec un texte en rouge "L'E-Mail DOIT être rempli", mais le rafraîchissement de la page va effacer tous les champs, et l'utilisateur est bon pour RE-remplir ses nom et prénom... Quelle punition ! Aussi, nous allons faire en sorte de mémoriser les données correctement saisies, et les remettre dans les champs correspondants.

Comment allons-nous faire ? Simplement en utilisant la propriété value des champs de formulaire, qui définissent la valeur par défaut des champs. Par exemple :

<input type="text" name="Nom" value="Dupont">

Va afficher un champ de saisie qui ne sera pas vide, mais contiendra Dupont, comme ceci :

Pour réafficher les données correctes, et pas simplement Dupont, nous allons simplement utiliser un echo de PHP :

Votre nom : <input type="text" name="Nom" value=<?echo $Nom;?>>

Si c'est la première fois qu'on arrive sur ce formulaire, comme $Nom ne vaut rien, value = Rien, et lorsque l'on clique sur Envoyer, s'il manque des champs, ils vont être réaffichés avec toujours rien dedans, mais un texte en rouge de mise en garde, et les champs correctement remplis seront répétés. Voici le code complet :

<body>
  <?
    if (($Nom <> "") && ($Prenom <> "") && ($EMail <> ""))
      {
      echo "Merci de vous être inscrit, " , $Prenom , " " , $Nom;
      exit;
      }
  ?>
  <form method="post" action="inscription.php">

    <!-- Gestion du nom : -->
    <?
      if (($Nom == "") && ($EnvoyerDonnee <> ""))
        echo "<font color='#FF0000'> Le Nom DOIT être rempli :</font><BR>";
    ?>
    Votre nom : <input type="text" name="Nom" value=<?echo $Nom;?>> <br>

    <!-- Gestion du Prénom : -->
    <?
      if (($Prenom == "") && ($EnvoyerDonnee <> ""))
        echo "<font color='#FF0000'> Le prénom DOIT être rempli :</font><BR>";
    ?>
    Votre prénom : <input type="text" name="Prenom" value=<?echo $Prenom;?>> <br>

    <!-- Gestion de l'E-Mail : -->
    <?
      if (($EMail == "") && ($EnvoyerDonnee <> ""))
        echo "<font color='#FF0000'> L'E-Mail DOIT être rempli :</font><BR>";
    ?>
    Votre E-Mail : <input type="text" name="EMail" value=<?echo $EMail;?>> <br>

    <input type="submit" name="EnvoyerDonnee" value="Envoyer">
  </form>
</body>

Vous pouvez le tester ici.

Validations particulières : L'E-Mail

Jusqu'ici, nous n'avons testé que le fait que les champs sont remplis ou non. Certains champs nécessitent une vérification plus pointue. L'E-Mail, par exemple, se doit non seulement d'être rempli, mais en plus de respecter les points suivants :

Cette liste de vérifications n'est pas exhaustive, mais il faut mettre des limites. D'autant que même si l'utilisateur entre un E-Mail qui à l'air valide, rien ne prouve qu'il le soit réellement ! Voyez cette page pour voir comment faire pour réellement prouver l'existence d'un E-Mail.

Dans la première section de code

<body>
  <?
    if (($Nom <> "") && ($Prenom <> "") && ($EMail <> ""))
      {
      echo "Merci de vous être inscrit, " , $Prenom , " " , $Nom;
      exit;
      }
  ?>

Création d'une fonction de validation d'E-Mail

Il ne suffit plus de simplement constater si s'E-Mail est rempli pour le valider, mais nous allons devoir faire toute une série de vérifications. Aussi, ne serait-il pas très élégant de créer une fonction ValideEMail() qui va s'occuper de ça ?

Remplaçons donc cette ligne de code
if (($Nom <> "") && ($Prenom <> "") && ($EMail <> ""))
par
if (($Nom <> "") && ($Prenom <> "") && (ValideEMail($EMail)==FALSE))

Et créons la fonction correspondante qui fait finalement strictement la même chose :

<?
  function ValideEMail($QuelleAdresse)
    {
    if ($QuelleAdresse == "")
      return FALSE;
    else
      return TRUE;

    }
?>
<html>
<head><title>Inscription</title></head>
<body>
<?
  if (($Nom <> "") && ($Prenom <> "") && (ValideEMail($EMail) == FALSE))
    {
    echo "Merci de vous être inscrit, " , $Prenom , " " , $Nom;
    exit;
    }
?>

Comme ça, nous allons pouvoir bien garnir cette fonction de toutes les vérifications >E-Mail nécessaires sans compliquer le reste de la page HTML.

D'ailleurs, nous n'allons pas nous contenter de renvoyer TRUE ou FALSE : En effet, dans le cas ou ValideEMail($QuelleAdresse)renvoie FALSE, ça veut dire que l'E-Mail est vide ... ou invalide (il n'est pas écrit correctement) - mais ça n'est pas encore géré. Ce que je voulais dire par là, c'est qu'en transformant un peu notre fonction comme ceci :

function ValideEMail($QuelleAdresse)
  {
  if ($QuelleAdresse == "")
    return "L'Email DOIT être rempli";
  else
    return TRUE;
  }

Elle renverra toujours TRUE si tout est correct, mais elle renverra carrément L'Email DOIT être rempli dans le cas ou l'E-Mail est vide. C'est très intéressant, parce qu'on constate qu'on va pouvoir retourner avec return soit TRUE si tout va bien, OK, mais autrement soit L'Email DOIT être rempli ou L'E-Mail que vous avez précisé est faux ou mal orthographié, selon les cas...

Car plus bas, nous avons :

<!-- Gestion de l'E-Mail : -->
<?
  if (($EMail == "") && ($EnvoyerDonnee <> ""))
    echo "<font color='#FF0000'> L'E-Mail DOIT être rempli :</font><BR>";

?>
Votre E-Mail : <input type="text" name="EMail" value=<?echo $EMail;?>> <br>

Que nous allons pouvoir personnaliser en incluant notre fonction ::

if (($EMail == "") && ($EnvoyerDonnee <> ""))
  echo "<font color='#FF0000'>" , ValideEMail($EMail) , "</font><BR>";

Et attention : Important ! On ne doit plus demander if (($EMail == "") && ($EnvoyerDonnee <> "")), mais simplement if ($EnvoyerDonnee <> "") car il y a maintenant d'autres raisons pour lesquelles un E-Mail ne peut pas être valide que le fait qu'il reste vide !

Voici le code complet à ce point :

<?
  function ValideEMail($QuelleAdresse)
    {
    if ($QuelleAdresse == "")
      return "L'Email DOIT être rempli";
    else
      return TRUE;
    }
?>

<html><head><title>Inscription</title></head>
<body>
  <?
    if (($Nom <> "") && ($Prenom <> "") && (ValideEMail($EMail)==TRUE))
      {
      echo "Merci de vous être inscrit, " , $Prenom , " " , $Nom;
      exit;
      }
  ?>
  <form method="post" action="inscription.php">
    <!-- Gestion du nom : -->
    <?
      if (($Nom == "") && ($EnvoyerDonnee <> ""))
        echo "<font color='#FF0000'> Le Nom DOIT être rempli :</font><BR>";
    ?>
    Votre nom : <input type="text" name="Nom" value=<?echo $Nom;?>> <br>

    <!-- Gestion du Prénom : -->
    <?
      if (($Prenom == "") && ($EnvoyerDonnee <> ""))
        echo "<font color='#FF0000'> Le prénom DOIT être rempli :</font><BR>";
    ?>
    Votre prénom : <input type="text" name="Prenom" value=<?echo $Prenom;?>> <br>

    <!-- Gestion de l'E-Mail : -->
     
<?
      if ($EnvoyerDonnee <> "")
        echo "<font color='#FF0000'>" , ValideEMail($EMail) , "</font><BR>";
    ?>
    Votre E-Mail : <input type="text" name="EMail" value=<?echo $EMail;?>> <br>

    <input type="submit" name="EnvoyerDonnee" value="Envoyer">
  </form>
</body>
</html>

Etoffage de la fonction ValideEMail

Vérifions qu'il n'existe pas de caractères interdits dans l'E-Mail

Maintenant que la structure globale de la page est en place nous allons enfin nous attaquer aux vérifications de l'E-Mail. Tout d'abord, nous allons vérifier si par hasard il n'y aurait pas des caractères interdits. En fait, nous allons plutôt vérifier si chacun des caractères de l'E-Mail est composé de :

strspn va nous y aider

Pour ce faire, nous allons utiliser la fonction strspn. Cette fonction va renvoyer le nombre de caractères qu'il y a dans une chaîne jusqu'à ce qu'il rencontre un caractère qui n'existe pas dans l'autre chaîne. Par exemple :
echo strspn("carrément", "abcdefghijklmnopqrstuvwxyz");

va renvoyer 4, car les 4 premiers caractères carr correspondent dans l'alphabet abcdefghijklmnopqrstuvwxyz. Pour qu'une chaîne soit valide, il faut que sa longueur (strlen) soit égal au retour de strspn, logique... ainsi :

$EMail = "jean-michel_dupont @uni.ge.ch";
if (strspn($EMail, "abcdefghijklmnopqrstuvwxyz0123456789-_@.") < strlen($EMail))
  echo "E-Mail invalide !";
else
  echo "E-Mail OK !";

Cet exemple renverrait "E-Mail invalide" à cause de l'espace juste avant le @.

Attention au fait qu'il ne faut pas pénaliser les utilisateurs qui utiliseraient des majuscules dans leurs E-Mails : Jean-Michel_DUPONT@Uni.Ge.Ch ne devrait pas être pénalisé, aussi préconisons la forme suivante :

if (strspn(strtolower($EMail), "abcdefghijklmnopqrstuvwxyz0123456789-_@.") < strlen($EMail))

Complétons la fonction avec la recherche des caractères invalides

La fonction s'écrirait alors comme ceci - Constatez que j'ai banni les "else", pour une question de simplification du code :

function ValideEMail($QuelleAdresse)
  {
  // SI l'E-Mail est carrément vide :
  if ($QuelleAdresse == "")
    return "L'Email DOIT être rempli";
  // Si l'E-Mail contient des caractères non autorisés dans une adresse mail correcte :
  if (strspn(strtolower($QuelleAdresse), "abcdefghijklmnopqrstuvwxyz0123456789-_@.") < strlen($QuelleAdresse))
    return "L'E-Mail que vous avez fourni contient des caractères non-autorisés";

  // Si on arrive ici, c'est que tout va bien : Le mail est syntaxiquement correct :
  return TRUE;

  }

Il y a encore une petite imperfection au niveau de l'affichage de l'erreur

Ce code marche parfaitement, mais il y a encore juste un truc qui me chatouille, c'est plus bas dans la page :

<!-- Gestion de l'E-Mail : -->
<?
  if ($EnvoyerDonnee <> "")
    echo "<font color='#FF0000'>" , ValideEMail($EMail) , "</font><BR>";
?>
Votre E-Mail : <input type="text" name="EMail" value=<?echo $EMail;?>> <br>

Admettons que dès la première fois, il entre son E-Mail correctement, mais qu'il revienne dans la page parce que, par exemple, le nom est laissé vide : Il va y avoir de toute façon cette ligne echo "<font color='#FF0000'>" , ValideEMail($EMail) , "</font><BR>"; qui va être affichée : C'est le code HTML qui écrit le message d'erreur de l'E-Mail en rouge... Or, comme l'E-Mail a été entré correctement, il va quand même écrire la valeur de TRUE (1 en fait), et ajouter le saut de ligne <BR>... Pas très professionnel, tout ça !

Moi, je verrai plutôt que c'est carrément la fonction qui formatte en rouge le message d'erreur et qui rajoute le <BR> à la fin, de manière é ce que ce soit écrit ici :

<!-- Gestion de l'E-Mail : -->
<?
  if ($EnvoyerDonnee <> "")
    echo ValideEMail($EMail);
?>
Votre E-Mail : <input type="text" name="EMail" value=<?echo $EMail;?>> <br>

Modifions donc notre fonction en conséquence :

function ValideEMail($QuelleAdresse)
  {
  // SI l'E-Mail est carrément vide :
  if ($QuelleAdresse == "")
    return "<font color='#FF0000'>L'E-Mail ne peut pas être vide</font><BR>";
  // Si l'E-Mail contient des caractères non autorisés dans une adresse mail correcte :
  if (strspn(strtolower($QuelleAdresse), "abcdefghijklmnopqrstuvwxyz0123456789-_@.") < strlen($QuelleAdresse))
    return "<font color='#FF0000'>L'E-Mail que vous avez fourni contient des caractères non-autorisés</font><BR>";
  // Si on arrive ici, c'est que tout va bien : Le mail est syntaxiquement correct :
  return "";
  }

N'oubliez pas de transformer le return TRUE en return "", parce que TRUE vaut 1, et 1, c'est un chiffre qui prend la place d'un caractère... Il ne faut donc pas, si la fonction a accepté de valider l'E-Mail, afficher quoi que ce soit, même pas 1 ! Et attention encore : De par ce fait, il faut bien penser à modifier le haut de la page :
if (($Nom <> "") && ($Prenom <> "") && (ValideEMail($EMail)==TRUE))
En :
if (($Nom <> "") && ($Prenom <> "") && (ValideEMail($EMail)==""))

Voici le code complet :

<?
  function ValideEMail($QuelleAdresse)
    {
    // SI l'E-Mail est carrément vide :
    if ($QuelleAdresse == "")
      return "<font color='#FF0000'>L'E-Mail ne peut pas être vide</font><BR>";
    // Si l'E-Mail contient des caractères non autorisés dans une adresse mail correcte :
    if (strspn(strtolower($QuelleAdresse), "abcdefghijklmnopqrstuvwxyz0123456789-_@.") < strlen($QuelleAdresse))
      return "<font color='#FF0000'>L'E-Mail que vous avez fourni contient des caractères non-autorisés</font><BR>";
   
 // Si on arrive ici, c'est que tout va bien : Le mail est syntaxiquement correct :
     return "";
    }

  ?>
<html>
<head><title>Inscription</title></head>
<body>
  <?

  if (($Nom <> "") && ($Prenom <> "") && (ValideEMail($EMail)==""))
    {
    echo "Merci de vous être inscrit, " , $Prenom , " " , $Nom;
    exit;
    }
  ?>
  <form method="post" action="inscription.php">
    <!-- Gestion du nom : -->
    <?
      if (($Nom == "") && ($EnvoyerDonnee <> ""))
        echo "<font color='#FF0000'> Le Nom DOIT être rempli :</font><BR>";
    ?>
    Votre nom : <input type="text" name="Nom" value=<?echo $Nom;?>> <br>
    <!-- Gestion du Prénom : -->
    <?
      if (($Prenom == "") && ($EnvoyerDonnee <> ""))
        echo "<font color='#FF0000'> Le prénom DOIT être rempli :</font><BR>";
    ?>
    Votre prénom : <input type="text" name="Prenom" value=<?echo $Prenom;?>> <br>

    <!-- Gestion de l'E-Mail : -->
    <?
      if ($EnvoyerDonnee <> "")
        echo ValideEMail($EMail);
    
?>
    Votre E-Mail : <input type="text" name="EMail" value=<?echo $EMail;?>> <br>

    <input type="submit" name="EnvoyerDonnee" value="Envoyer">
  </form>
</body>
</html>

Que vous pouvez tester en cliquant ici (Essayez d'entrer des E-Mails faux comme Rien du tout, ###@truc.com, puis un réel E-Mail comme le vôtre)

Uniformisation des procédures de validation

Pour l'instant, nous sommes focalisé sur l'E-Mail : le nom et le prénom n'ont d'autre validation que le fait qu'ils soient vides... Bon, mais on pourrait imaginer que par la suite, nous voudrions d'autres contrôles, comme par exemple empêcher les noms qui contiennent des chiffres, ou un prénom qui contienne plus de 20 caractères... Bref, tel quel, notre code n'est pas évolutif : Concernant l'E-Mail, nous savons exactement ou placer nos autres instructions de contrôle, mais si nous voulions effectuer des contrôles de validation sur le nom et le prénom, il nous faudrait construire des fonctions telles que ValidationNom et ValidationPrenom.

Construisons-les donc immédiatement sur le mèdèle de ValidationEMail, de manière à nous simplifier la vie par la suite :

<?
  function ValideNom($QuelNom)
    {
    // SI le nom est carrément vide :
    if ($QuelNom == "")
      return "<font color='#FF0000'>Le nom ne peut pas être vide</font><BR>";
    // *** PLACER ICI LES INSTRUCTIONS DE VALIDATION ***
    // Si on arrive ici, c'est que tout va bien : Le nom est syntaxiquement correct :
    return "";
    }
  function ValidePrenom ($QuelPrenom)
    {
    // SI le prénom est carrément vide :
    if ($QuelPrenom == "")
      return "<font color='#FF0000'>Le Prénom ne peut pas être vide</font><BR>";
    // *** PLACER ICI LES INSTRUCTIONS DE VALIDATION ***
    // Si on arrive ici, c'est que tout va bien : Le prénom est syntaxiquement correct :
    return "";
    }

  function ValideEMail($QuelleAdresse)
    {
    // SI l'E-Mail est carrément vide :
    if ($QuelleAdresse == "")
      return "<font color='#FF0000'>L'E-Mail ne peut pas être vide</font><BR>";
    // Si l'E-Mail contient des caractères non autorisés dans une adresse mail correcte :
    if (strspn(strtolower($QuelleAdresse), "abcdefghijklmnopqrstuvwxyz0123456789-_@.") < strlen($QuelleAdresse))
      return "<font color='#FF0000'>L'E-Mail que vous avez fourni contient des caractères non-autorisés</font><BR>";
    // *** PLACER ICI LES (autres) INSTRUCTIONS DE VALIDATION ***
    // Si on arrive ici, c'est que tout va bien : Le mail est syntaxiquement correct :
    return "";
    }

?>

Sans oublier de corriger le code du bas de la page :

<?
if (($Nom == "") && ($EnvoyerDonnee <> ""))
echo "<font color='#FF0000'> Le Nom DOIT être rempli :</font><BR>";
?>

et
<?
if (($Prenom == "") && ($EnvoyerDonnee <> ""))
echo "<font color='#FF0000'> Le prénom DOIT être rempli :</font><BR>";
?>

en

<? if ($EnvoyerDonnee <> "" echo ValideNom($Nom); ?>
et
<? if ($EnvoyerDonnee <> "" echo ValidePrenom($Prenom); ?>

J'en ai profiter pour compresser le code PHP sur une seule ligne. Maintenant, nous avons un code puissant, efficace, évolutif et propre. Voici la nouvelle version qui, vous en conviendrez certainement, est un modèle de facilité de maintenance :

<?
  function ValideNom($QuelNom)
    {
    // SI le nom est carrément vide :
    if ($QuelNom == "")
      return "<font color='#FF0000'>Le nom ne peut pas être vide</font><BR>";
    // *** PLACER ICI LES INSTRUCTIONS DE VALIDATION ***
    // Si on arrive ici, c'est que tout va bien : Le nom est syntaxiquement correct :
    return "";
    }

  function ValidePrenom ($QuelPrenom)
    {
    // SI le prénom est carrément vide :
    if ($QuelPrenom == "")
      return "<font color='#FF0000'>Le Prénom ne peut pas être vide</font><BR>";
    // *** PLACER ICI LES INSTRUCTIONS DE VALIDATION ***
    // Si on arrive ici, c'est que tout va bien : Le prénom est syntaxiquement correct :
    return "";
    }

  function ValideEMail($QuelleAdresse)
    {
    // SI l'E-Mail est carrément vide :
    if ($QuelleAdresse == "")
      return "<font color='#FF0000'>L'E-Mail ne peut pas être vide</font><BR>";
    // Si l'E-Mail contient des caractères non autorisés dans une adresse mail correcte :
    if (strspn(strtolower($QuelleAdresse), "abcdefghijklmnopqrstuvwxyz0123456789-_@.") < strlen($QuelleAdresse))
      return "<font color='#FF0000'>L'E-Mail que vous avez fourni contient des caractères non-autorisés</font><BR>";
    // *** PLACER ICI LES INSTRUCTIONS DE VALIDATION ***
    // Si on arrive ici, c'est que tout va bien : Le mail est syntaxiquement correct :
    return "";
    }
?>
<html>
  <head>
    <title>Inscription</title>
  </head>
  <body>
    <?
      if (($Nom <> "") && ($Prenom <> "") && (ValideEMail($EMail)==""))
        {
        echo "Merci de vous être inscrit, " , $Prenom , " " , $Nom;
        exit;
        }
    ?>
    <form method="post" action="inscription.php">
      <!-- Gestion du nom : -->
      <? if ($EnvoyerDonnee <> "" echo ValideNom($Nom); ?>
      Votre nom : <input type="text" name="Nom" value=<?echo $Nom;?>> <br>

      <!-- Gestion du Prénom : -->
      <? if ($EnvoyerDonnee <> "") echo ValidePrenom($Prenom); ?>
      Votre prénom : <input type="text" name="Prenom" value=<?echo $Prenom;?>> <br>

      <!-- Gestion de l'E-Mail : -->
      <? if ($EnvoyerDonnee <> "") echo ValideEMail($EMail); ?>
      Votre E-Mail : <input type="text" name="EMail" value=<?echo $EMail;?>> <br>

      <input type="submit" name="EnvoyerDonnee" value="Envoyer">
    </form>
  </body>
</html>

Revenons à ValideEMail : Y-a-il bien une seule fois le signe @ ?

Pour ce faire, nous allons utiliser la fonction substr_count, qui va compter le nombre d'occurence d'une chaîne il y a dans une autre, par exemple :

print substr_count("a@b@c@d", "@");

Vous aurez compris que pour que l'E-Mail soit valide, il faut qu'il y ait un @, et pas 0 ni 2 ni plus !. Corriger la fonction est maintenant un vrai jeu d'enfant : voici la ligne qui permet de vérifier qu'il y a au moins une fois le @ :

function ValideEMail($QuelleAdresse)
  {
  // SI l'E-Mail est carrément vide :
  if ($QuelleAdresse == "")
    return "<font color='#FF0000'>L'E-Mail ne peut pas être vide</font><BR>";
    // Si l'E-Mail contient des caractères non autorisés dans une adresse mail correcte :
  if (strspn(strtolower($QuelleAdresse), "abcdefghijklmnopqrstuvwxyz0123456789-_@.") < strlen($QuelleAdresse))
    return "<font color='#FF0000'>L'E-Mail que vous avez fourni contient des caractères non-autorisés</font><BR>";

  if (substr_count($QuelleAdresse , "
@") == 0)
    return "<font color='#FF0000'>Un E-Mail DOIT contenir le signe
@</font><BR>";
  // *** PLACER ICI LES INSTRUCTIONS DE VALIDATION ***
  // Si on arrive ici, c'est que tout va bien : Le mail est syntaxiquement correct :
  return "";
  }

... Et voici la portion de code qui permet de vérifier qu'il n'y en a pas plusieurs, évidemment

if (substr_count($QuelleAdresse , "@") > 1)
  return "<font color='#FF0000'>Un E-Mail ne peut contenir plus d'un signe @</font><BR>";

@ ne peut être à l'extrémité d'un E-Mail

Il faut maintenant contrôler si ce n'est pas le premier ni le dernier caractère de l'E-Mail : pour vérifier cet état de fait, nous allons utiliser la fonction intégrée strpos qui va nous donner la position de ce @ (nous savons maintenant qu'il y en a un, ni plus ni moins puisque nous venons de le vérifier). exemple :

                      01234
$UnEMailQuelconque = "@jean";
echo strpos($UnEMailQuelconque, "@"); // 0
$UnEMailQuelconque = "jean@";
echo strpos($UnEMailQuelconque, "@"); // 4

Ainsi, il va suffire d'analyser l'E-Mail avec strpos($EMail, "@"), et si le résultat est 0 ou ... strlen($EMail) (qui est la longueur de la chaîne, je le rappelle), alors on peut sans problème affirmer que l'E-Mail n'est pas valide :

if ((strpos($QuelleAdresse , "@")==0) || (strpos($QuelleAdresse , "@")==strlen($QuelleAdresse)))
  return "<font color='#FF0000'>Un E-Mail ne peut commencer ni finir avec le signe @</font><BR>";

ATTENTION au piège : strpos($QuelleAdresse , "@") va retourner la position de @ à partir de 0 :
strpos("abc@" , "@") va retourner 2 (0 , 1 , 2). Mais strlen ("abc@") va retourner 3 car il y a 3 caractères. Ainsi, il faut apporter une petite modification :

if ((strpos($QuelleAdresse , "@")==0) || (strpos($QuelleAdresse , "@")==strlen($QuelleAdresse)-1))
  return "<font color='#FF0000'>Un E-Mail ne peut commencer ni finir avec le signe @</font><BR>";

Nous verrons un peu plus bas que l'extrémité de l'E-Mail ne peut pas être autre chose qu'une lettre.

Y'a-t-il bien au moins un point soit à la 4ème position avant la fin ou à la 3ème ?

Il y a 2 possibilités : machin@bidule.com - Ou machin@bidule.ch (ou machin@bidule.org, .edu, .us, .fr, .tv ...) Il y a soit 2 ou 3 lettres à la fin de l'E-Mail, mais ni plus ni moins. Il y a bien une possibilité pour que des adresses telles que machin@bidule.info ou d'autres domaines en 4 lettres voient le jour, mais actuellement, ce n'est pas le cas. Et quand bien même ce serait le cas, il ne nous sera pas difficile de corriger notre code PHP, puisque nous avons justement pris soin qu'il soit évolutif (Scindage en fonctions).

Pour ce faire, nous allons utiliser les indices (les crochets [ et ]), comme ceci :

                    111111111122
          0123456789012345678901
$EMail = "luc.dupont@truc.uni.fr";
echo $EMail[0]; // affiche l (L minuscule)

Je rappelle que strlen($EMail) va lui, renvoyer 22 car il compte les caractères à partir de 1. donc :

                    111111111122
          0123456789012345678901

$EMail = "luc.dupont@truc.uni.fr";
echo $EMail[strlen($EMail)-3]; // va bien afficher le 19ème caractère : le point.
                 22       19

C'est donc maintenant facile : Il va suffire de comparer le -3ème et le -4ème caractère :

if (($EMail[strlen($EMail)-3] == ".") || ($EMail[strlen($EMail)-4] == "."))
  echo "Il y a bien un point au bon endroit";
else
  echo "Il manque un point";

Implémentons à présent notre travail dans la fronction ValideEMail : si il y a un point à la bonne place, ne rien faire : {}, sinon, renvoyer un message d'erreur :

if (($QuelleAdresse[strlen($QuelleAdresse)-3] == ".") || ($QuelleAdresse[strlen($QuelleAdresse)-4] == "."))
  {}
else
  return "<font color='#FF0000'>Il manque un point dans votre E-Mail, ou il est mal placé</font><BR>";

Ce qui fait que notre fonction est de mieux en mieux garnie :

function ValideEMail($QuelleAdresse)
  {
  // SI l'E-Mail est carrément vide :
  if ($QuelleAdresse == "")

    return "<font color='#FF0000'>L'E-Mail ne peut pas être vide</font><BR>";
  // Si l'E-Mail contient des caractères non autorisés dans une adresse mail correcte :
  if (strspn(strtolower($QuelleAdresse), "abcdefghijklmnopqrstuvwxyz0123456789-_@.") < strlen($QuelleAdresse))
    return "<font color='#FF0000'>L'E-Mail que vous avez fourni contient des caractères non-autorisés</font><BR>";

  if (substr_count($QuelleAdresse , "@") == 0)
    return "<font color='#FF0000'>Un E-Mail DOIT contenir le signe @</font><BR>";

Attention : Joël-Ange m'informe que cette ligne de code ne fonctionne pas lors du premier affichage (sans doute dû à la version de PHP), mais celle-ci fonctionne :

if ((strlen($mail)>1)&&(substr_count($QuelleAdresse , "@") == FALSE))
                   echo "<font color='#FF0000'>Un E-Mail DOIT contenir le signe @</font>


  if (substr_count($QuelleAdresse , "@") > 1)
    return "<font color='#FF0000'>Un E-Mail ne peut contenir plus d'un signe @</font><BR>";

  if ((strpos($QuelleAdresse , "@")==0) || (strpos($QuelleAdresse , "@")==strlen($QuelleAdresse)-1))
    return "<font color='#FF0000'>Un E-Mail ne peut commencer ni finir avec le signe @</font><BR>";

  if (($QuelleAdresse[strlen($QuelleAdresse)-3] == ".") || ($QuelleAdresse[strlen($QuelleAdresse)-4] == "."))
    {}
  else
    return "<font color='#FF0000'>Il manque un point dans votre E-Mail, ou il est mal placé</font><BR>";

  // *** PLACER ICI LES INSTRUCTIONS DE VALIDATION ***
  // Si on arrive ici, c'est que tout va bien : Le mail est syntaxiquement correct :
  return "";

  }

Vous pouvez tester cette nouvelle version ici. Essayez d'entrer comme E-Mail :

L'E-Mail ne doit mesurer entre 6 et 50 caractères

En effet, moins de 6 caractères, ce n'est pas possible (a@a.fr), et plus de 50, c'est qu'il y a quand même un problème également

         111111111122222222223333333333444444444
123456789012345678901234567890123456789012345678
jean-pascal_delamotte@gros-machin.bidule.uni.org

Pas de commentaire particulier :

if (strlen($QuelleAdresse) < 6)
  return "<font color='#FF0000'>L'E-Mail doit mesurer au moins 6 caractères</font><BR>";
if (strlen($QuelleAdresse) >= 50)
  return "<font color='#FF0000'>L'E-Mail ne peut excéder 50 caractères</font><BR>";

Extrémités de l'E-Mail

Nous avons vu un peu plus haut qu'il n'est pas possible d'avoir le signe @ en début ou en fin de chaîne. En fait, le premier et le dernier caractère d'un E-Mail doit être une lettre. Tout l'e-mail doit être constitué des caractères
abcdefghijklmnopqrstuvwxyz0123456789-_@.
Mais, en outre, le premier et le dernier caractères doit être constitué des caractères
abcdefghijklmnopqrstuvwxyz

Pour ce faire, nous allons utiliser à nouveau la fonction intégrée strspn (comme dans la toute première validation : les caractères interdits). Mais cette fois, ce n'est pas tout l'E-Mail que nous allons tester, mais juste le premier et le dernier caractère :
$EMail = "truc@machin.com";
echo strspn($EMail[0], "abcdefghijklmnopqrstuvwxyz");
va afficher 1, et
$EMail = ".truc@machin.com";
echo strspn($EMail[0], "abcdefghijklmnopqrstuvwxyz");
Affiche 0.

                    111111
          0123456789012345
$EMail = "truc@machin.com.";
echo strspn($EMail[strlen($EMail)-1], "abcdefghijklmnopqrstuvwxyz");
Donne 0. Ce qui donne :

$EMail = ".truc@machin.com";
if ((strspn($EMail[0], "abcdefghijklmnopqrstuvwxyz") == 0) || (strspn($EMail[strlen($EMail)-1], "abcdefghijklmnopqrstuvwxyz") == 0))
  echo "Le premier et le dernier catactère de l'E-Mail doit être une lettre";

et dans la fonction :

if ((strspn($QuelleAdresse[0], "abcdefghijklmnopqrstuvwxyz") == 0) || (strspn($QuelleAdresse[strlen($QuelleAdresse)-1], "abcdefghijklmnopqrstuvwxyz") == 0))
  return "<font color='#FF0000'>Le premier et le dernier catactère de l'E-Mail doit être une lettre</font><BR>";

Y a-t-il plusieurs points d'affilée, ou @. ou .@?

La dernière vérification à faire est qu'il n'y a pas 2 ou plusieurs points l'un à côté de l'autre : Il peut y avoir plusieurs points dans une adresse E-Mail, mais pas l'un à côté de l'autre :

luc.dupont@machin.com est correct mais
luc..dupont@machin.com ne l'est pas
luc.dupont.@machin.com non plus, et
luc.dupont@.machin.com non plus

Nous allons à nouveau utiliser strpos :

echo strpos("ab@.ef", "@.");
Affiche 2, et
echo strpos("ab@cd", "@.");
N'affiche rien, même pas 0.

Il faut donc que strpos ne renvoie rien pour que l'E-Mail soit valide. La fonction se complète ainsi :

Longueur maximum des champs

Nul besoin d'une procédure PHP pour limiter la taille maximum des champs, en effet :

<input type="text" name="EMail" maxlength="3">

---