Partage
  • Partager sur Facebook
  • Partager sur Twitter

Imposer nombre de caractères minimum formulaire

    23 janvier 2023 à 18:49:49

    Bonjour à tous,

    Mon formulaire de contact est spammé. Je reçois de courts messages de seulement quelques mots pris au hasard dans une phrase. L'adresse mail est à chaque fois différente ainsi que le nom. Le point récurrent est dans le textarea avec ces 4 ou 5 mots. Je pense qu'en conditionnant la validation du textarea à un minimum de caractères, cela m'éviterai beaucoup de désagrément avec ce bot.

    Je comprends bien le html et css mais suis un vrai noob en php. Le php est bien trop précis pour moi. Une virgule, un espace et ça marche pas. Bref, cela fait plus de 3 heures que je cherche à ajouter une condition à mon code php !! J'ai creusé vers les str_len mais ca marche pas. J ai essayé de gratter avec les attributs html de textarea, rien... Je suis coincé... Voici le php de mon formulaire de contact. Merci d'avance pour votre aide.

    <?php
    
    	$to = 'xxx@yahoo.fr';  // please change this email id
    	
    	$errors = array();
    	// print_r($_POST);
    
    	// Check if name has been entered
    	if (!isset($_POST['name'])) {
    		$errors['name'] = 'Please enter your name';
    	}
    	
    	// Check if email has been entered and is valid
    	if (!isset($_POST['email']) || !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
    		$errors['email'] = 'Please enter a valid email address';
    	}
    	
    	//Check if message has been entered
    	if (!isset($_POST['message'])) {
    		$errors['message'] = 'Please enter your message';
    	}
    	
    
    	$errorOutput = '';
    
    	if(!empty($errors)){
    
    		$errorOutput .= '<div class="alert alert-danger alert-dismissible" role="alert">';
     		$errorOutput .= '<button type="button" class="close" data-dismiss="alert" arialabel="Close"><span aria-hidden="true">&times;</span></button>';
    
    		$errorOutput  .= '<ul>';
    
    		foreach ($errors as $key => $value) {
    			$errorOutput .= '<li>'.$value.'</li>';
    		}
    
    		$errorOutput .= '</ul>';
    		$errorOutput .= '</div>';
    
    		echo $errorOutput;
    		die();
    	}
    
    
    
    	$name = $_POST['name'];
    	$email = $_POST['email'];
    	$message = $_POST['message'];
    	$from = $email;
    	$subject = 'Contact Form : mywebsite';
    	
    	$body = "From: $name\n E-Mail: $email\n Message:\n $message";
    
    
    	//send the email
    	$result = '';
    	if (mail ($to, $subject, $body)) {
    		$result .= '<div class="alert alert-success alert-dismissible" role="alert">';
     		$result .= '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>';
    		$result .= 'Merci! Nous répondrons à votre demande dans les meilleurs délais';
    		$result .= '</div>';
    
    		echo $result;
    		die();
    	}
    
    	$result = '';
    	$result .= '<div class="alert alert-danger alert-dismissible" role="alert">';
    	$result .= '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>';
    	$result .= 'Oups! Certainement un soucis avec les serveurs web... Essayez à nouveau plus tard.';
    	$result .= '</div>';
    
    	echo $result;
    	die();
    
    
    ?>
    	


    J'ai essayé plein de trucs. le str_len en condition supplémentaire et le dernier auquel je croyais vraiment... Ben... Ca plante à chaque fois... :)

    	//Check if message has been entered
    	if (!isset($_POST['message']) && str_len($_POST['textarea']) > 30)) {
    		$errors['message'] = 'Please enter your message';
    	}



    -
    Edité par eckso7 23 janvier 2023 à 21:03:03

    • Partager sur Facebook
    • Partager sur Twitter
      23 janvier 2023 à 21:23:22

      Bonjour, pas d'underscore entre str et len, voir PHP: strlen - Manual

      A noter que strlen renvoi la taille de la chaîne de texte en bits et pas en caractères ce qui peut parfois donner des comportement inattendu, avec les caractères encoder sur plusieurs bits.

      Par exemple:

      <?php
      
      echo strlen("test"); // 4
      
      echo strlen("tést"); // 5

       Les accents, les caractères spéciaux sont quasiment tous encoder sur plusieurs bits.

      Pour mesurer la taille de la chaîne de texte en nombres de caractères et pas en bits il vaudra mieux utiliser mb_strlen

      PHP: mb_strlen - Manual

      //Check if message has been entered
      if (!isset($_POST['message']) && mb_strlen($_POST['textarea']) > 30)) {
          $errors['message'] = 'Please enter your message';
      }

      Pense éventuellement à activer l'extension mbstring dans ton php.ini si ce n'est pas déjà fait pour pouvoir utiliser les fonction mb_*

      Il faut juste retirer le point-virgule (;) devant l'extension, sauvegarder le fichier et redémarrer le serveur local.  

      ;extension=mbstring

      EDIT:

      J'ai un peu passé sous silence le fait que c'est surement pas une bonne façon de bloquer les spams (essentiellement parce que ça ne les bloques pas) tu peux essayer d'implémenter un reCaptcha qui sera surement plus efficace:

        reCAPTCHA v3  |  Google Developers

      Peut-être que l'API Askimet peut bloquer ce genre de spam aussi:

      API Documentation - Learn all about our API | Akismet




      -
      Edité par SamuelGaborieau3 23 janvier 2023 à 21:28:57

      • Partager sur Facebook
      • Partager sur Twitter

      suggestion de présentation.

        23 janvier 2023 à 22:33:14

        Merci beaucoup Samuel. Je me mets dessus !

        Et merci pour la formulation très courtoise et remarque constructive pour la méthode. D'autres personnes aurait usé un ton plus cinglant. Encore merci pour cette bienveillance. Car je me doute avec mes petites connaissances que ce n'est effectivement pas une méthode très orthodoxe mais c'est vraiment pour répondre à un bot un peu relou et spécifique. 

        Et de plus, cela me permet de me familiariser avec php mais je vois bien mes lacunes sur la rigueur d'écriture. Rien n'est pardonné !

        Je crois savoir que recaptcha est un service gratuit de google mais en fait, tu fais du taff pour les IA de google. Je vais donc plutôt me pencher sur Akismet pour de futurs projets. Merci pour le conseil ;)

        EDIT:

        Je viens d'essayer mais ça plante. J'ai bien repris ton code :

        <?php
        
        	$to = 'xxxx@xxx.fr';  // please change this email id
        	
        	$errors = array();
        	// print_r($_POST);
        
        	// Check if name has been entered
        	if (!isset($_POST['name'])) {
        		$errors['name'] = 'Please enter your name';
        	}
        	
        	// Check if email has been entered and is valid
        	if (!isset($_POST['email']) || !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
        		$errors['email'] = 'Please enter a valid email address';
        	}
        	
        	//Check if message has been entered
        	if (!isset($_POST['message']) && mb_strlen($_POST['textarea']) > 30)) {
        	    $errors['message'] = 'Please enter your message';
        	}
        
        	$errorOutput = '';
        
        	if(!empty($errors)){
        
        		$errorOutput .= '<div class="alert alert-danger alert-dismissible" role="alert">';
         		$errorOutput .= '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>';
        
        		$errorOutput  .= '<ul>';
        
        		foreach ($errors as $key => $value) {
        			$errorOutput .= '<li>'.$value.'</li>';
        		}
        
        		$errorOutput .= '</ul>';
        		$errorOutput .= '</div>';
        
        		echo $errorOutput;
        		die();
        	}
        
        
        
        	$name = $_POST['name'];
        	$email = $_POST['email'];
        	$message = $_POST['message'];
        	$from = $email;
        	$subject = 'Contact From xxx';
        	
        	$body = "From: $name\n E-Mail: $email\n Message:\n $message";
        
        
        	//send the email
        	$result = '';
        	if (mail ($to, $subject, $body)) {
        		$result .= '<div class="alert alert-success alert-dismissible" role="alert">';
         		$result .= '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>';
        		$result .= 'Merci! Nous répondrons à votre demande dans les meilleurs délais';
        		$result .= '</div>';
        
        		echo $result;
        		die();
        	}
        
        	$result = '';
        	$result .= '<div class="alert alert-danger alert-dismissible" role="alert">';
        	$result .= '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>';
        	$result .= 'Oups! Certainement un soucis avec les serveurs web... Essayez à nouveau plus tard.';
        	$result .= '</div>';
        
        	echo $result;
        	die();
        
        
        ?>
        	

        Je n'ai pas trouvé de fichier php.ini. J'en ai donc crée un avec la ligne indiquée et l'ai placé dans le dossier php:

        ;extension=mbstring

        Avec ou sans le point virgule, j'ai essayé mais ça ne fonctionne pas. Je ne vois pas de message d'erreur concernant l'extension.

        J 'ai un message d'erreur qui me parait venir de firefox lui-même lors du clic de l envoi du formulaire avec mb_strlen.



        J'ai aussi essayé ceci:

        //Check if message has been entered
        	if (!isset($_POST['message']) && mb_strlen($_POST['message']) > 30)) {
        	    $errors['message'] = 'Please enter your message';
        	}

        En me disant que ce n'est pas textarea que je veux checker mais message , et cela ne marcha pas non plus...

        -
        Edité par eckso7 23 janvier 2023 à 23:35:56

        • Partager sur Facebook
        • Partager sur Twitter
          24 janvier 2023 à 7:59:26

          Bonjour l'erreur semble venir de Javascript et pas de PHP.

          Il y a une parenthèse de trop à la fin de la condition:

          //Check if message has been entered
          if (!isset($_POST['message']) && mb_strlen($_POST['textarea']) > 30) {
              $errors['message'] = 'Please enter your message';
          }

          Mais je pense pas que le message d'erreur vienne de là.

          Est-ce que tu as un code Javascript qui réagit au clique sur le bouton envoyé ?

          Pour trouver ton fichier php.ini tu peux aller dans un terminal et effectuer la commande:

          php --ini

          Qui doit te renvoyer un résultat comme celui-ci:

          Configuration File (php.ini) Path:
          Loaded Configuration File:         C:\<PATH>\php.ini
          Scan for additional .ini files in: C:\<PATH>\conf.d;
          Additional .ini files parsed:      C:\<PATH>\php.ini

          Le fichier de configuration php est indiqué par cette ligne:

          Loaded Configuration File:         C:\<PATH>\php.ini

          Ce fichier tu peux l'ouvrir puis faire un ctrl+f pour ouvrir le menu de recherche de mots puis entrer:

          extension=mbstring

          Et si il y a un point-virgule (;) avant le mot extension tu peux l'enlever pour activer l'extension, puis sauvegarder le fichier et redémarrer le serveur local.




          -
          Edité par SamuelGaborieau3 24 janvier 2023 à 8:00:10

          • Partager sur Facebook
          • Partager sur Twitter

          suggestion de présentation.

            24 janvier 2023 à 22:27:57

            Bonsoir Samuel,

            Effectivement, le message d'erreur n'est pas lié à la parenthèse.

            Merci d'avoir éclairci le point du point virgule :) Ce site est en ligne depuis longtemps, il ne tourne donc pas en local. Dois-je vérifier sur le serveur de ovh? Je pense que tout est en ordre de ce coté là, non?

            Pour javascript, je ne vois rien concernant le bouton dans le global.js. Bref, je coince...

            J'ai essayé de prendre le problème par un autre bout. Interdire les urls dans le corps du message. J'ai donc ajouté une condition à la suite des 3 premières:

                // Check if links in message... 
            	if(preg_match('/http(s?):\/\//ism',$message)) {
            		$errors['message'] = 'No url plz';
                }



            Là, ça ne plante pas le site comme à toutes mes tentatives précédentes. Je reçois bien le mail mais les urls passent :D

            Je me suis rendu compte que si je ne rempli pas un des champs (nom ou email) du formulaire, il s'affiche un message en français: "Veuillez compléter ce champ". Or dans le php, les messages d'erreur sont visiblement en anglais. Il y a donc quelque chose d'autre derrière ! Impossible de trouver. Ce n'est pas dans le html, css, global.js, ni le php.

            Une idée de comment je pourrai retrouver cet action? En inspectant,  je vois au hover que ça active une classe css "form-control" mais je ne retrouve nulle part cette phrase: "Veuillez compléter ce champ"

             

            -
            Edité par eckso7 24 janvier 2023 à 23:01:59

            • Partager sur Facebook
            • Partager sur Twitter
              25 janvier 2023 à 1:18:36

              Re bonjour, la phrase "veuillez compléter ce champs" dans l'info bulle vient du navigateur c'est parce que tu as du mettre le champ en required.

              <input type="email" name="..." required />

              Le navigateur détecte que le champs doit être rempli avant l'envoi du formulaire.

              Ce n'est pas un message d'erreur de PHP le formulaire n'est pas envoyé à PHP à ce moment-là.

              C'est plutôt le "Error occurd! Please try again." qu'il faudrait trouvé, sur la capture d'écran ça à l'air de provenir d'un appel à alert du genre:

              alert("Error Occurd! Please try again.");

              Qui doit être situé quelque part dans ton Javascript, au moment où tu envoi ton formulaire.

              Le message d'erreur est trop générique pour qu'on sache d'où vient le problème.

              Est-ce que ça empêche l'envoi du formulaire ?

              Est-ce que ton code PHP est exécuter quand même ?

              Tu peux peut-être essayer de désactiver ton Javascript dans un premier temps au moins pour voir si le traitement de ton formulaire fonctionne.



              • Partager sur Facebook
              • Partager sur Twitter

              suggestion de présentation.

                25 janvier 2023 à 19:55:50

                « les caractères spéciaux sont quasiment tous encodés sur plusieurs bits »

                Tous les caractères le sont. ;)

                • Partager sur Facebook
                • Partager sur Twitter
                  27 janvier 2023 à 21:14:28

                  Bonjour,

                  Merci Domi de cette précision. Samuel, navré de n'avoir répondu avant, ces 2 dernières journées furent chargées.

                  J'ai trouvé le bout de js qui s'exécute:

                  $("#contactForm").submit(function (e) {
                  
                          e.preventDefault();
                          var $ = jQuery;
                  
                          var postData = $(this).serializeArray(),
                              formURL = $(this).attr("action"),
                              $cfResponse = $('#contactFormResponse'),
                              $cfsubmit = $("#cfsubmit"),
                              cfsubmitText = $cfsubmit.text();
                  
                          $cfsubmit.text("Sending...");
                  
                  
                          $.ajax(
                              {
                                  url: formURL,
                                  type: "POST",
                                  data: postData,
                                  success: function (data) {
                                      $cfResponse.html(data);
                                      $cfsubmit.text(cfsubmitText);
                                      $('#contactForm input[name=name]').val('');
                                      $('#contactForm input[name=email]').val('');
                                      $('#contactForm textarea[name=message]').val('');
                                  },
                                  error: function (data) {
                                      alert("Error occurd! Please try again");
                                  }
                              });
                  
                          return false;
                  
                      });

                  C'est bien celui-ci, il manque bien le "e" à "occurd"!

                  Pour tes 2 questions précédentes:

                  Est-ce que ça empêche l'envoi du formulaire ? js désactivé, le formulaire est envoyé et reçu correctement. Clicker sur le bouton fait basculer sur une page "contact.php" sans aucune mise en forme avec le texte de validation d'envoi enregistré dans le php

                  Est-ce que ton code PHP est exécuter quand même ? Oui , le message est reçu dans la boite mail.

                  Je vois dans le js qu 'il demande bien la validation de "name+email+message". C'est bizarre que le mb_strlen fasse tout planter. Il y a un truc à faire dans le js?

                  -
                  Edité par eckso7 28 janvier 2023 à 17:24:29

                  • Partager sur Facebook
                  • Partager sur Twitter
                    28 janvier 2023 à 14:45:21

                    "Merci Domi de cette précision"

                    En fait, je faisais un petit clin d’œil taquin à Samuel, qui est toujours très pertinent et d'une grande aide car, sur le coup, il a confondu bit et octet (byte en anglais). Je pensais qu'il allait corriger de lui-même.

                    Pour rappel, si on se limite aux caractères anglais et autres caractères courants, non accentués, les caractères peuvent être encodés sur 7 bits. Les caractères occidentaux ont d'une manière générale ont besoins d'un octet (8 bits). C'est ce qui était utilisé massivement jusqu'à il n'y a pas longtemps par le charset (jeu de caractères) ISO 8859-1 et ses variantes. L'UTF-8, bien plus universel, continue à utiliser un octet pour les caractères encodés en ISO, mais encode sur deux, voire trois octets les caractère qui sont pour nous exotiques. Comme pour toute règle, il y a des exceptions. Vu le peu de ralentissement et les opportunités qu'il offre (🕾, 🖊, ➽,😃, etc), il s'est imposé sur le web. Les polices ne contiennent pas toutes l'ensemble du jeu.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      28 janvier 2023 à 15:04:45

                      Merci, en tous cas, à vous 2 pour votre bienveillance ;)

                      • Partager sur Facebook
                      • Partager sur Twitter
                        28 janvier 2023 à 16:10:30

                        > L'UTF-8, bien plus universel, continue à utiliser un octet pour les caractères encodés en ISO, mais encode sur deux, voire trois octets les caractère qui sont pour nous exotiques.

                        1. ASCII (non étendu) pas ISO : UTF-8 est un sur-ensemble à l'ASCII (ie les points de code sont les mêmes et encodés de la même manière)
                        2. c'est sur jusqu'à 4 octets qu'un point de code peut être encodé en UTF-8

                        -
                        Edité par julp 28 janvier 2023 à 16:13:03

                        • Partager sur Facebook
                        • Partager sur Twitter
                          28 janvier 2023 à 17:53:43

                          Bonjour, en effet, j'ai confondu bit et byte.

                          Tu rentres actuellement dans le cas error de tas requête AJAX, donc le navigateur considère que la réponse du serveur est une erreur par apport à la réponse qu'il attend.

                          Le premier problème que je vois, c'est que tu déclares ton verbe HTTP (POST) dans l'attribut "type" au lieu de l'attribut "method".

                          Tu peux aussi afficher l'origine du problème en cas d'erreur avec :

                          // helper: error( jqXHR: $.jqXHR, textStatus: string, errorThrown: string);
                          error: function (jqXHR, textStatus, errorThrown) {
                          
                          	console.warn(`> POST request has failed with: ${textStatus} => ${errorThrown}`)
                              alert(`Error occured! debug: ${textStatus} => ${errorThrown}`);
                          }

                          J'imagine que l'erreur vient du fait que par défaut les requête réseaux sont envoyées en GET et pas en POST et que comme tu définis la méthode dans l'attribut "type" au lieu de "method" ta requête par en "GET" et du coup la superglobale $_POST est un tableau vide.

                          -
                          Edité par SamuelGaborieau3 28 janvier 2023 à 17:57:30

                          • Partager sur Facebook
                          • Partager sur Twitter

                          suggestion de présentation.

                            28 janvier 2023 à 19:58:05

                            Je viens d'essayer avec "method" à la place de POST dans
                                            type: "POST",
                            

                            en minuscule et majuscule (au cas où) et ça me refais le même message d'erreur du js lors du click sur le bouton.

                            Je me remet dessus demain avec ton code pour le debug. J'espère avoir bien compris. Je rajoute le bout de code dans mon php, je fais la procédure d'envoi et devrait s'afficher l'erreur sur la page contact.php qui s'ouvrira. Merci encore ;)

                            • Partager sur Facebook
                            • Partager sur Twitter

                            Imposer nombre de caractères minimum formulaire

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            • Editeur
                            • Markdown