2012-01-13 4 views
1

En ce moment, j'essaie de valider un formulaire en utilisant PHP. Le problème est que, même après avoir entré quelque chose de mal, PHP l'interprète comme juste. Évidemment, je ne comprends pas pourquoi, même si j'ai une hypothèse. Voici le code:Validation de formulaire PHP ne fonctionne pas - plusieurs questions

if(isset($_GET['contact'])){ 

    // Validation functions 

    // Name 
    function validate_name(){ 
     $name  = $_POST['customer']; 
     if(strlen($name) > 0){ 
      trim(mysql_real_escape_string($name)); 
      return true; 
     }else { 
      return false; 
     } 
    } 

    // Mail 
    function validate_mail(){ 
     $mail  = $_POST['mail']; 
     if(preg_match('/^[a-zA-Z0-9._%+-][email protected][a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/', $mail) && strlen($mail) > 0){ 
      return true; 
     }else { 
      return false; 
     } 
    } 

    // Message 
    function validate_message(){ 
     $message = $_POST['message']; 
     if(strlen($message) > 0){ 
      trim(mysql_real_escape_string($message)); 
      return true; 
     }else { 
      return false; 
     } 
    } 

    validate_name(); 
    validate_mail(); 
    validate_message(); 

    if(validate_name == true && validate_mail == true && validate_message == true){ 
     echo "Ok!"; 
    }else{ 
     echo "Error!"; 
    } 
} 

Une chose que je sais est mauvais est le suivant: if(validate_name == true && validate_mail == true && validate_message == true){}. Mais si je ne me trompe pas, cela fonctionne toujours parce que PHP peut gérer quelque chose comme ça (PHP donne seulement un avis, pas une erreur). Mais comment faire les choses correctement, il doit y avoir un meilleur moyen?

La seconde que j'ai découverte est que PHP appelle fondamentalement les fonctions correctes, mais à l'intérieur des fonctions le if-else ne fonctionne pas. Pourquoi? Je ne comprends pas ...

+0

'PHP donne seulement un avis, pas une erreur 'Qu'en est-il de la correction de l'avis ?? – PeeHaa

+0

C'est pourquoi je demande comment le faire mieux. – Sven

+0

Vous pouvez le faire mieux en fixant l'avis de c. Puisque vous n'avez pas ajouté l'avis, je devine juste. Mais vous faites: 'validate_name'. Qu'est-ce que c'est??? – PeeHaa

Répondre

2

OK. Comme c'est le week-end et que je n'ai rien de mieux à faire, je vais corriger vos problèmes et vous expliquer ce qui ne va pas avec votre code.

Pour commencer par répondre à votre question initiale:

PHP donne seulement un avis

Comme les avis indique:

Avis: L'utilisation de validate_name constante indéfinie - supposé ' validate_name 'in ...

Ceci est dû à la ligne où vous faites:

if(validate_name == true ... 

validate_name est rien. S'il s'agissait d'une variable, il aurait été $validate_name s'il s'agissait d'un appel de fonction validate_name(). Donc PHP suppose que c'est une constante. Sans se plaindre de savoir si c'est un mouvement intelligent de PHP essayant de vous «aider», il fait ce qu'il fait. Donc, fondamentalement, PHP le traitera comme une constante avec une valeur de validate_name.

Alors, que PHP n'est la suivante:

if ('somestring' == true) // this will always be truthy. 

Maintenant, pour fixer plus/améliorer votre code:

Je suis également pas sûr de votre utilisation de superglobales. Vous utilisez $_GET['contact'] et également $_POST['customer']. Donc, vous mélangez _POST et _GET. Cela pourrait être correct pas sûr cependant.

Si vous avez un formulaire avec une action de '/file.php?contact=something' et que la méthode de formulaire est définie sur post cela convient parfaitement.


Il serait également préférable d'ajouter des paramètres aux fonctions.Donc changer:

function validate_name(){ 

Pour

function validate_name($name){ 

Au lieu de se fonder sur les valeurs _POST. De cette façon, vous pouvez tester votre code sans avoir besoin de données postales.


Dans votre validate_name et validate_message fonction vous faites ceci:

trim(mysql_real_escape_string($name)); 
trim(mysql_real_escape_string($message)); 

Il y a deux choses mal avec ceci:

  1. Il est disponible uniquement dans le cadre de la fonction et vous ne le retournez pas (alors pourquoi le feriez-vous?)
  2. Les noms de fonctions indiquent qu'il valide, non pas qu'il ses affaires.

Dans votre fonction e-mail de validation vous procédez comme suit:

if(preg_match('/^[a-zA-Z0-9._%+-][email protected][a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/', $mail) && strlen($mail) > 0){ 

Outre le fait que je suis sûr que ce regex ne reçoit pas tous les EmailAddresses valides, il aurait été préférable de Vérifiez d'abord si la chaîne est rempli


maintenant, pour corriger toutes vos questions dans le code suivant:.

if(isset($_GET['contact'])){ 

    function validate_name($name) 
    {   
     if(strlen($name) === 0) { 
      return false; 
     } 

     return true; 
    } 

    function validate_mail($mail) 
    { 
     if (strlen($mail) === 0 || filter_var($mail, FILTER_VALIDATE_EMAIL)) { 
      return false; 
     } 

     return true; 
    } 

    function validate_message($message) 
    { 
     if(strlen($message) === 0) { 
      return false; 
     } 

     return true; 
    } 

    if(validate_name($_POST['customer']) && validate_mail($_POST['mail']) && validate_message($_POST['message'])) { 
     echo "Ok!"; 
    } else { 
     echo "Error!"; 
    } 
} 
+1

Juste une correction mineure: Au lieu de 'filter_var ($ email, FILTER_VALIDATE_EMAIL)' il doit être 'filter_var ($ mail, FILTER_VALIDATE_EMAIL)'. – Sven

3

Je vois 3 problèmes à ce jour:

  1. vos fonctions sont juste retour vrai ou faux, pas la variable fournie modifiée. En outre, les variables sont soumises à la portée de la fonction, elles ne sont donc pas disponibles en dehors de la fonction, si vous les modifiez simplement à l'intérieur et ne les renvoyez pas, ou n'utilisez pas de variables globales.
    Si vous ne renvoyez pas les valeurs, alors, pourquoi les rogner et les échapper?
  2. mysql_real_escape_string() fonctionne si une connexion est active, sinon retourne FALSE.
  3. dans votre cas() condition, vous utilisez « validate_name » mais il est la syntaxe est erronée, à la fois si vous aviez l'intention comme une variable ou une fonction (entre parenthèses manquante)

Prendre votre première fonction, pour . ex, vous pourriez faire (à condition que vous avez une connexion active):

function validate_name($customer){ 
     if(strlen($customer) > 0){ 
      $customer = trim(mysql_real_escape_string($customer)); 
      return $customer; 
     }else { 
      return false; 
     } 
    } 

et plus tard:

if(validate_name($_POST['customer'] AND ....) 

une autre chose que je vois, depuis validate_name() et validate_message() effectuent les mêmes opérations, pourquoi ne pas en faire une seule (par exemple, validate($postIndex)), en passant l'index $ _POST en paramètre? C'est un peu plus sec. Comme:

$name = validate($_POST['customer']); 
$message = validate($_POST['message']); 
$email = validate_email($_POST['email']); 
if($name AND $email AND $message){ 

// now here you also have the trimmed/escaped values to work with. 
} 
+0

Un gotcha à surveiller pour évaluer une chaîne comme un booléen, est de garder à l'esprit ce qui se traduit par 'true' et ce qui se traduit par' false'. Bien que peu probable, un message valide est peut-être la chaîne "0". Cela va évaluer comme faux si converti en un booléen. Si vous deviez le faire de cette façon, je suggérerais de changer l'instruction if en 'if ($ name! == false && $ email! == false && $ message! == false)'. – Travesty3

+0

@Damien Je déconseille de créer une fonction générique 'validate()'. Que faire si vous souhaitez ajouter d'autres conditions pour le message (par exemple, vérifier les caractères minimum/maximum). Mieux vaut le rendre plus générique en créant une fonction comme: 'isMinimumLength ($ string, $ length = 0)'. Vous pouvez maintenant utiliser cette fonction dans les fonctions 'validate_ *'. De cette façon, vous pouvez facilement ajouter des contrôles supplémentaires aux fonctions de validation. – PeeHaa

+0

@Damien +1 pour le commentaire sur la connexion active. – PeeHaa

3

Le premier problème, est que vos fonctions renvoient un résultat booléen, elles ne représentent pas une valeur persistante. Vous êtes si conditionnel consiste simplement à vérifier si les constantes "validate_name", "validate_mail" et "validate_message" sont définies. PHP en rencontrant une constante indéfinie mettra la constante égale à lui-même. Ensuite, la contrainte de type compare les valeurs de chaîne "validate_name", "validate_mail" et "validate_message" à true, ce qui est le cas en convertissant à la fois la valeur booléenne true et les valeurs de chaîne en valeur 1. Ils sont ensuite considérés comme égaux.

Ce que vous devez faire est:

$isNameOk = validate_name(); 
$isMessageOk = validate_message(); 
$isMailOk = validate_mail(); 

if($isNameOk && $isMessageOk && $isMailOk) 
    echo "Ok!"; 
else 
    echo "Error!"; 

Les secondes erreurs sont sans rapport avec ce que vous faites les fonctions. Vous définissez des variables telles que $ name, $ mail et $ message dans la portée de la fonction (ce qui est bien), mais vous émettez aussi trim et mysql_escape sans re-définir la valeur à la variable.-À-dire qu'il devrait être:

$name = trim(mysql_escape_string($name)); 

En plus de cela, vous appliquez ces assainisseurs de valeur à vos variables mais vos fonctions ne font rien avec ces variables. Je suppose que vous voulez utiliser ultérieurement les variables $ name, $ mail et $ message dans votre script. Cependant, car ils sont définis dans la portée de la fonction locale qui ne fonctionnera jamais.

La solution rapide est de définir vos variables dans la portée globale et de les référencer dans la fonction avec le mot-clé global mais c'est moche. Une meilleure solution serait d'objectiver votre code et de faire de ces valeurs et fonctions des membres d'un objet de classe.

class Validator { 
    protected $name; 
    protected $isNameOk; 
    protected $mail; 
    protected $isMailOk; 
    protected $message; 
    protected $isMessageOk; 

    public function validate($data) { 
     $this->isNameOk = $this->checkAndSanitizeName($data['name']); 
     $this->isMessageOk = $this->checkAndSanitizeMessage($data['message']); 
     $this->isMailOk = $this->checkAndSanitizeMail($data['mail']); 
     if($this->isNameOk && $this->isMessageOk && $this->isMailOk) 
      return true; 
     return false; 
    } 

    protected function checkAndSanitizeName($name) { 
     $this->name = trim(mysql_real_escape_string($name)); 
     if(strlen($name) > 0) 
      return true; 
     return false; 
    } 

    protected function checkAndSanitizeMail($mail) { 
     $this->mail = trim(mysql_real_escape_string($mail)); 
     if(preg_match('/^[a-zA-Z0-9._%+-][email protected][a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/', $this->mail) && strlen($this->mail) > 0) 
      return true; 
     return false; 
    } 

    protected function checkAndSanitizeMessage($message) { 
     $this->message = trim(mysql_real_escape($mail)); 
     if(strlen($this->message) > 0) 
      return true; 
     return false; 
    } 

    public function getName() { return $this->name; } 
    public function getMail() { return $this->mail; } 
    public function getMessage() { return $this->message; } 
    public function isMailOk() { return $this->isMailOk; } 
    public function isNameOk() { return $this->isNameOk; } 
    public function isMessageOk(){ return $this->isMessageOk; } 
} 

utilisation serait:

$validator = new Validator(); 
if($validator->validate($_POST)) 
{ 
    echo "Ok!"; 
    echo "Thanks " . $validator->getName() . " for posting your message."; 
} 
else 
{ 
    echo "Error!"; 
    if(!$validator->isMailOk()) 
     echo "Mail was invalid"; 
    // etc. 
} 

Je me suis cogné ce code dans la zone de réponse afin de prendre avec un grain de sel. Peut-être besoin de quelques fautes de frappe.

+0

Bien que sympa et tout, y a-t-il une classe entière comme celle nécessaire pour valider 3 champs d'entrée? OP n'a pas précisé la largeur de son projet, c'est peut-être juste un simple formulaire de contact. Dans une image plus grande, une classe de validateur c'est une bonne fonctionnalité, bien que –

+0

Bien que la classe soit en effet un peu surdimensionnée pour ce projet, ce post m'a vraiment aidé à comprendre comment cela fonctionnerait. Merci! – Sven

2
  1. changement validate_name == true juste validate_name(). Cela appellera la fonction et retournera le booléen. Pas besoin de comparer quelque chose qui est déjà un booléen à un autre booléen afin de produire un booléen ... il suffit d'utiliser la valeur retournée. Faites la même chose pour les deux autres fonctions.
  2. Dans vos fonctions, vous appelez les fonctions trim() et mysql_real_escape_string(), mais vous ne sauvegardez pas ces modifications. Ceux-ci ne sont pas transmis par référence, vous devez donc enregistrer la modification dans vos variables $_POST.

Voici le code mis à jour:

if(isset($_GET['contact'])){ 

    // Validation functions 

    // Name 
    function validate_name(){ 
     $name  = $_POST['customer']; 
     if(strlen($name) > 0){ 
      $_POST["customer"] = trim(mysql_real_escape_string($name)); 
      return true; 
     }else { 
      return false; 
     } 
    } 

    // Mail 
    function validate_mail(){ 
     $mail  = $_POST['mail']; 
     if(preg_match('/^[a-zA-Z0-9._%+-][email protected][a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/', $mail) && strlen($mail) > 0){ 
      return true; 
     }else { 
      return false; 
     } 
    } 

    // Message 
    function validate_message(){ 
     $message = $_POST['message']; 
     if(strlen($message) > 0){ 
      $_POST["message"] = trim(mysql_real_escape_string($message)); 
      return true; 
     }else { 
      return false; 
     } 
    } 

    if(validate_name() && validate_mail() && validate_message()){ 
     echo "Ok!"; 
    }else{ 
     echo "Error!"; 
    } 
} 
1

On dirait que vous n'êtes pas appeler les fonctions que vous avez écrit dans le cas du bloc. Vous pouvez également raccourcir cette déclaration.

if(validate_name() && validate_mail() && validate_message()) {echo 'Ok!';}

Parce que tous ces éléments sont des résultats booléens retournaient, l'instruction if ne nécessite pas explicite == vrai chèque. En outre, vous devez prendre soin de désinfecter toutes les variables GET/POST.

1

Vous devez modifier un peu le dernier bit de code. comme ceci:

if(validate_name() && validate_mail() && validate_message()){ 
    //do stuff with the info here 
}else{ 
    echo "Error!"; 
    //display error information and show them the form again. 
} 
1

Vous pouvez le faire par exemple:
Son pas la meilleure solution, mais affiche aucun avis ou des erreurs. codage heureux.

if(isset($_GET['contact'])){ 
    // Validation functions 
    // Name 
    function validate_name(){ 
     if(!isset($_POST['customer'])) { 
      return false; 
     } 
     if(strlen($_POST['customer']) > 0){ 
      $_POST['customer'] = trim($_POST['customer']); 
      return true; 
     }else { 
      return false; 
     } 
    } 

    // Mail 
    function validate_mail(){ 
     if(!isset($_POST['mail'])) { 
      return false; 
     } 
     return preg_match('/^[a-zA-Z0-9._%+-][email protected][a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/', $_POST['mail']); 

    } 

    // Message 
    function validate_message(){ 
     if(!isset($_POST['message'])) { 
      return false; 
     } 
     if(strlen($_POST['message']) > 0){ 
      $_POST['message'] = trim($_POST['message']); 
      return true; 
     } else { 
      return false; 
     } 
    } 

    if(validate_name() == true && validate_mail() == true && validate_message() == true){ 
     echo "Ok!"; 
    }else{ 
     echo "Error!"; 
    } 
} 
Questions connexes