Une fonction utilisateur qui pose problème.

Résolu/Fermé
trevino - 3 sept. 2017 à 16:20
jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 - 4 sept. 2017 à 20:06
Bonjour,
Je viens de terminer d'écrire un petit formulaire d'inscription, avec quelques fonctions personnalisées. Cependant, 2 erreurs surviennent lorsque je commence à tester le travail "fini" :

1) Quand je ne remplis pas tous les champs, j'obtiens une erreur indiquant qu'au moins un champ est vide (normal, j'ai défini une constante qui contient ce texte, et la condition du if(...) n'est pas remplie) ;

2) Quand j'essaie de remplir convenablement les champs pour réaliser une "vraie" inscription. Si elle réussit, je veux voir s'afficher un texte (en l'occurrence, 'OK !'), sans envoyer les infos dans une bdd. Le problème : une fonction (que j'ai créé) fait des caprices et ne remplit pas la condition du second if(...).

Pourriez-vous m'aider à corriger ma/mes fonction.s et/ou mon formulaire ?
Merci d'avance :)

fonctions.php
<?php

function secure_password($password)
{
  if(preg_match("#[a-z]#",$password) AND preg_match("#[A-Z]#",$password) AND preg_match("#[0-9]#",$password) AND strlen($password)>7)
  {
    return 1;
  }
  else {
    return 0;
  }
}

function allowed_chars($str)
{
  if(preg_match('#^[a-zA-Z0-9._\[\]\|\$\!@=\+&-]$#',$str)) // Caractères spéciaux autorisés :  ._[]|$!@=+&-
  {
    return 1;
  }
  else
  {
    return 0;
  }
}

function valid_username($username)
{
  if (allowed_chars($username) AND strlen($username)>5 AND strlen($username)<33)
  {
    return 1;
  }
  else
  {
    return 0;
  }
}


constants.php
<?php

define('WEBSITE_NAME','example.com');

// MAILING CONSTANTS
// Change the following constants to correspond to your own website.
// It is particularly important for website with newsletter, confirmation's mail,...
// Be careful with WEBSITE_SENDING_EMAIL (and possibly WEBSITE_EMAIL_SENDER) since some spam filters block addresses that
// does not match with the informations in the 'From: ...' part of the mail's header.

define('WEBSITE_EMAIL_SENDER','no-reply');
define('WEBSITE_SENDING_EMAIL','***@***');
define('WEBSITE_EMAIL_RECEIVER','replying-add');
define('WEBSITE_RECEIVING_EMAIL','***@***');

// ERRORS CONSTANTS
// Change the following constants to correspond to you own functions and errors
// Please, note that each occurences of an error must be modified in each files where it appears if you modify its name.

define('ERR_EMPTY_FIELDS','An error occured: at least one obligatory field is empty. Please, fill all marked fields.');
define('ERR_EMAIL_WRONG_FORMAT','An error occured: the format of the string does not match with the format of an email address.');
define('ERR_EMAIL_NOT_MATCH','An error occured: the email address does not match its confirmation.');
define('ERR_EMAIL_USED','An error occured: the email address is already in use.'); // You can also give a link to restore the user's account.
define('ERR_USERNAME_UNKNOWN','An error occured: the username is not registered.'); // You can also give a link to create an account.
define('ERR_USERNAME_WRONG_FORMAT', 'An error occured: the username is incorrect.');
define('ERR_USERNAME_USED','An error occured: the username is already in use.');
define('ERR_PASSWORD_NOT_MATCH','An error occured: the password does not match its confirmation.');
define('ERR_PASSWORD_TOO_WEAK','An error occured: the password is too weak.'); // See the function secure_password to define a secure password.
define('ERR_LOGIN_NOT_MATCH', 'An error occured: the password does not match the username.'); // Same as ERR_EMAIL_USED
define('ERR_MUST_BE_CONNECTED','An error occured: you have to be connected to access this page.'); // You can give a link to the connection's page.


inscription.php
<?php

session_start();
require_once('fonctions.php');
require_once('constants.php');

if(isset($_POST['confirm']))
{
  $username=htmlspecialchars($_POST['username']);
  $user_email=htmlspecialchars($_POST['mail1']);
  $user_email_confirm=htmlspecialchars($_POST['mail2']);
  $user_password=$_POST['password1'];
  $user_password_confirm=$_POST['password2'];
  $error_message="";

  if(!empty($username) AND !empty($user_email) AND !empty($user_email_confirm) AND !empty($user_password) AND !empty($user_password_confirm))
  {
    if(valid_username($username))
    {
      if(already_used_username($username)==0)
      {
        if($user_email==$user_email_confirm)
        {
          if(valid_email($user_email))
          {
            if(already_used_email($user_email)==0)
            {
              if($user_password==$user_password_confirm)
              {
                if(secure_password($user_password))
                {
                  $error_msg='OK !';
                }
                else
                {
                  $error_msg=ERR_PASSWORD_TOO_WEAK;
                }
              }
              else
              {
                $error_msg=ERR_PASSWORD_NOT_MATCH;
              }
            }
            else
            {
              $error_msg=ERR_EMAIL_USED;
            }
          }
          else
          {
            $error_msg=ERR_EMAIL_WRONG_FORMAT;
          }
        }
        else
        {
          $error_msg=ERR_EMAIL_NOT_MATCH;
        }
      }
      else
      {
        $error_msg=ERR_USERNAME_USED;
      }
    }
    else
    {
      $error_msg=ERR_USERNAME_WRONG_FORMAT;
    }
  }
  else
  {
    $error_msg=ERR_EMPTY_FIELDS;
  }
}

?>

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>S'inscrire</title>
  </head>
  <body>
    <div>
      <h2>Inscription</h2>
      <?php if(!empty($error_msg)){echo '<span id="remarque_erreur">'.$error_msg.'</span><br /><br />';} ?>
      <form method="POST" action="">
        <table>
          <tr>
            <td>
              <input type="text" placeholder="Pseudo" name="username" <?php if(!empty($username)){echo 'value="'.$username.'"';} ?> />
            </td>
          </tr>
          <tr>
            <td>
              <input type="email" placeholder="Mail de contact" name="mail1" <?php if(!empty($user_email)){echo 'value="'.$user_email.'"';} ?> />
            </td>
          </tr>
          <tr>
            <td>
              <input type="email" placeholder="Confirmation" name="mail2" <?php if(!empty($user_email_confirm)){echo 'value="'.$user_email_confirm.'"';} ?> />
            </td>
          </tr>
          <tr>
            <td>
              <input type="password" placeholder="Mot de passe" name="password1" />
            </td>
          </tr>
          <tr>
            <td>
              <input type="password" placeholder="Confirmation du mot de passe" name="password2" />
            </td>
          </tr>
        </table>
        <input type="submit" value="Envoyer" name="confirm" />
      </form>
    </div>
  </body>
</html>

3 réponses

yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
Modifié le 3 sept. 2017 à 16:33
bonjour,
je te suggère d'utiliser TRUE et FALSE au lieu de 1 et 0.
je te suggère aussi d'ajouter des
echo
pour afficher ce que ton code fait et que contiennent tes variables.
quelle est la fonction qui ne se comporte pas comme tu t'y attends?
pour cette fonction, que passes-tu précisément comme paramètre, qu'attends-tu comme résultat?
0
J'avais déjà mis TRUE (resp. FALSE) à la place des 1 (resp. 0).

-> Où devrais-je mettre les
echo
?

-> La fonction qui me pose problème est la fonction valid_username. Elle prend en paramètre une chaîne de caractère, et se charge de vérifier 2 caractéristiques : si sa longueur est comprise entre 5 et 33 caractères, et si les caractères utilisés sont validés par la regex.
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476 > trevino
3 sept. 2017 à 17:22
au début de valid_username, avant le if, ajoute
echo $username;

tu n'as pas répondu: quelle est la valeur de $username quand tu appelles la fonction valid_username, et qu'attends-tu comme réponse: 0 ou 1?
tu peux ajouter des echo aussi avant chaque return, par exemple:
echo 'function allowed_chars return 1';

cela t'aidera à comprendre à quel moment ton code ne fait pas ce que tu crois avoir demandé.
tu peux aussi faire, par exemple:
echo preg_match('#^[a-zA-Z0-9._\[\]\|\$\!@=\+&-]$#','trevino');
, pour vérifier si tu as bien codé la fonction preg_match.
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476 > trevino
3 sept. 2017 à 17:33
tu n'as pas expliqué ce que tu attendais de la regex, ce qu'elle devait accepter et ce qu'elle devait refuser.
0
jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650
3 sept. 2017 à 22:36
Bonjour,

pour commencer.. la fonction htmlspecialchar n'est à utiliser QUE pour l'affichage.
En aucun cas pour récupérer les données ...

Ensuite, regarde la priorité des opérateurs (https://www.php.net/manual/fr/language.operators.precedence.php )
Perso.. je préfère le && au lieu du AND


Puis, pour ce qui est de l'écriture de ton code... tu pourrais un peu plus utiliser l'écriture ternaire au lieude faire des IF / ELSE
Par exemple, ce code :
function allowed_chars($str)
{
  if(preg_match('#^[a-zA-Z0-9._\[\]\|\$\!@=\+&-]$#',$str)) // Caractères spéciaux autorisés :  ._[]|$!@=+&-
  {
    return 1;
  }
  else
  {
    return 0;
  }
}

peut s'écrire plus "proprement" comme ceci :
function allowed_chars($str) {
  return preg_match('#^[a-zA-Z0-9._\[\]\|\$\!@=\+&-]$#',$str) ? true : false;
}

voir même dans ce cas précis :
function allowed_chars($str) {
  return preg_match('#^[a-zA-Z0-9._\[\]\|\$\!@=\+&-]$#',$str);
}




NB : Pour ce qui est de la récupération des données ainsi que ton premier IF .. je te conseille de remplacer ceci :
 $username=htmlspecialchars($_POST['username']);
  $user_email=htmlspecialchars($_POST['mail1']);
  $user_email_confirm=htmlspecialchars($_POST['mail2']);
  $user_password=$_POST['password1'];
  $user_password_confirm=$_POST['password2'];
  $error_message="";

  if(!empty($username) AND !empty($user_email) AND !empty($user_email_confirm) AND !empty($user_password) AND !empty($user_password_confirm))
  {

par :
//récupération PROPRE des variables
$username = !empty($_POST['username']) ? $_POST['username'] : NULL;
$user_email = !empty($_POST['mail1']) ? $_POST['mail1'] : NULL;
$user_email_confirm = !empty($_POST['mail2']) ? $_POST['mail2'] : NULL;
$user_password = !empty($_POST['password1']) ? $_POST['password1'] : NULL;
$user_password_confirm = !empty($_POST['password2']) ? $_POST['password2'] : NULL;

//ici tu peux aussi ajouter (le temps des tests) un print de $_POST pour voir si ce qu'il retourne est conforme à ce que tu attends
echo "<pre> Variables POST :<br>";
print_r($_POST);
echo "</pre>";


//autre variable
$error_message="";

//IF ...
if($username && $user_email && $user_email_confirm && $user_password && $user_password_confirm){



NB² : Même si ce n'est pas une obligation... il existe une norme pour écrire son code. La norme PSR.
En l'occurence... elle propose d'écrire les IF (et if/else.. ) de la manière suivante (avec l'accolade sur la même ligne...) :
if(condition) {
  //...
} elseif(condtion) {
  //...
} else {
 //...
}

cela rendra ton code plus lisible .....

Pour finir, en ce qui concerne la "logique" de ton code...
Je commencerai par vérifier si le user et/ou l'email est déjà utilisé avant d'aller regarder si il est "valide".


0
Merci à tous :)

Jordane : j'ai appliqué tes recommandations (en particulier l'écriture ternaire, au moins pour la récupération des variables).

yg_be : j'ai pris soin de corriger la regex. Je voulais qu'elle accepte une chaîne de caractère de longueur comprise entre 6 et 32 caractères (intervalle fermé). La chaîne de caractère pouvait contenir les lettres de A à Z (insensible à la casse, puisque j'ai inclus les deux classes [a-z] et [A-Z]), les chiffres de 0 à 9, et les caractères spéciaux suivants : ._[]|$!@=+&-

Le problème, c'est qu'en faisant ainsi, je n'indiquais pas la longueur. J'ai donc fait une fonction qui répondait à toutes mes exigences en fusionnant allowed_chars() et valid_username(). À la fin, voici ce que j'obtiens :

function allowed_username($str) {
  return preg_match('#^[a-zA-Z0-9._\[\]\|\$\!@=\+&-]{6,32}$#',$str); // Caractères spéciaux autorisés :  ._[]|$!@=+&-
}


Plus claire, plus concise, cette fonction fait son job :)
Maintenant, ma page d'inscription fonctionne correctement, c'est tout ce que je voulais.

Pour finir, j'aimerais savoir Jordane pourquoi tester si l'username est déjà pris avant de voir s'il est valide ?
0
jordane45 Messages postés 38144 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 21 avril 2024 4 650
4 sept. 2017 à 20:06
Pour eviter une etape inutile.. si il est deja pris tu te moques de savoir si il est valide... puisque..ben...il est déjà pris...
0