Page 1 sur 1

array, foreach, if, preg_mach : je n'y arrive pas...

Posté : 16 avr. 2008, 18:57
par slec
Bonjour,

Je suis nouveau sur le forum et grand débutant PHP. Je précise que je ne suis plus tout jeune (63 ans) et donc que c'est dur pour moi l'apprentissage de ce langage (j'avais bien capté HTML et CSS pourtant !). J'ai essayé de trouver des infos sur internet et dans ce forum mais ça ne colle pas avec mon problème aussi j'ai décidé de l'exposer. Merci à tous ceux qui voudront bien me donner un coup de main.

Je fais une sorte de livre d'or. Mais je voudrais interdire l'usage de certains mots dans les post sur le site (pour éviter les insultes, les provocations, etc...).

J'ai consulté mon petit manuel de PHP que j'ai acheté mais je ne m'en sort pas. J'ai une page de formulaire où les gens saisissent leur nom et leur message. J'envoie tout ça dans une table tb_livredor dans MySQL. Jusque là tout fonctionnait bien. Mais depuis3 jours un petit malin insère des insultes sur le site. Je dois donc contrôler ce qui est saisi dans le textarea. Voici ce que je pensais faire :

- mettre mes mots interdits dans un tableau (array)
- comparer chaque mot du message posté à ceux de mon tableau (foreach ... preg_match)
- afficher un message "Désolé, ce message ne peut être inséré" si message contient un mot interdit (if)
- sinon insérer le message (else)

Jusque là, ça va... Mais voici mon code et là ça va plus du tout :
// Le texte du message
$message = stripslashes(htmlentities($_POST["message"]));

// RESOLUTION PROBLEME INJURE
$tableauMotsInterdits = array('cretin', 'debile', 'connard'); 
foreach($tableauMotsInterdits as $cle) 
    { 
     if(preg_match($cle,$message)= true){ 
 echo "Désolé, vous ne pouvez poster ce message"; }
 else { [Requete d'insertion]}
}
Et là j'ai un beau message d'erreur !!
Encore merci de votre aide à tous

Posté : 16 avr. 2008, 19:32
par caroube
Regarde la doc et les exemples http://fr3.php.net/manual/fr/function.preg-match.php

avec preg_match, il faut que le mot (ou l'expression que tu recherches) soit délimitée : par un / par exemple.
ensuite, il faut que tu mettes un indicateur pour signaler que la recherche doit être indifférenciée sur les majuscules/minuscules.

donc par exemple
preg_match("/".$cle/"/i", $message)
ensuite, il faut distinguer le = du == : = c'est pour assigner une valeur et == pour tester une valeur
donc
if (preg_match("/".$cle/"/i", $message)== true){  
Enfin, pour le fun : le if teste une valeur true ou false, mais preg_match renvoie le nombre d'occurrences de la chaîne trouvée. Il faudrait donc écrire :
if (preg_match("/".$cle/"/i", $message) > 0){  
Mais comme 0 c'est false et tout autre valeur est true, ta syntaxe fonctionne. Cependant, preg_match () == true va renvoyer true si le résultat de preg_match est true et false si son résultat est false. Donc tu peux simplifier :
if (preg_match("/".$cle/"/i", $message)){  

Re: array, foreach, if, preg_mach : je n'y arrive pas...

Posté : 16 avr. 2008, 19:32
par ouckileou
Et là j'ai un beau message d'erreur !!
Qui est ? :)

Posté : 16 avr. 2008, 19:42
par ouckileou
À part ça, je trouve un peu bizarre de prendre les mots 1 par 1 et d'utiliser une expression régulière sur chacun... à ce moment autant faire une bête comparaison de chaîne non ? L'expression régulière devrait servir à vérifier tout le texte.

Edition : je viens de lire le code et ce n'est pas ce que tu fais, c'est cette phrase qui m'a trompé : "comparer chaque mot du message posté à ceux de mon tableau (foreach ... preg_match) "

Mais pourquoi ne pas déjà utiliser des fonctions plus simples, comme par exemple :
http://php.net/strstr : Trouve la première occurrence dans une chaîne
http://php.net/substr_count : Compte le nombre d'occurrences de segments dans une chaîne

Ce serait déjà un premier pas non ?

Voir ici pour les fonctions de manipulation de chaîne : http://fr3.php.net/manual/fr/ref.strings.php

Enfin je suis persuadé que ce type de question à déjà été posé sur le forum ;)

Posté : 17 avr. 2008, 09:57
par slec
Merci à tous de votre aide.

En fait, ouckileou, j'utilise preg_match parce que ma liste de mots interdits est potentiellement longue et j'ai lu quelques part que cette fonction "tirait" moins sur les ressources du serveur (je suis en mutualisé sur un hébergement à bas coût).

Concernant le code corrigé que tu m'as fourni Caroube, j'ai toujours un problème de message d'erreur : Parse error: parse error in c:\program files\easyphp1-8\www\site_association\poster_message.php on line 32
J'ai eu l'idée de mettre de coté ma requête d'insertion pour voir si c'était ça qui posait problème mais ça continue !! J'ai tout enlevé de la page pour ne garder que le strict minimum pour tester la fonction mais l'erreur persiste. A ligne 32 : il n'y a rien : c'est la fin du fichier.
// Le texte du message
$message = stripslashes(htmlentities($_POST["message"]));

// RESOLUTION PROBLEME INJURE 
$tableauMotsInterdits = array('cretin', 'debile', 'connard');  
foreach($tableauMotsInterdits as $cle)  {  
     if (preg_match("/".$cle."/i", $message)){  
	 echo "Désolé, vous ne pouvez poster ce message."; 
	 } 
	 else {   
	 echo "Tout c'est bien passé : pas d'injure !!!";
	 }

Posté : 17 avr. 2008, 10:03
par steph29
une accolade mal fermée?

Posté : 17 avr. 2008, 10:42
par slec
Merci, merci Steph29... Je venais de trouver tout seul (et pas peu fier) !

Voici mon nouveau problème c'est que ça ne fait pas tout à fait ce que je veux : comme j'ai utilisé une boucle foreach, ça réécrit autant de fois ma petite phrase qu'il y a de mot dans ma liste. Ce n'est pas exactement ce que je veux : je souhaite que s'il rencontre un des mots dans le tableau il exécute telle action et s'il ne rencontre pas alors il exécute telle autre action.

Je ne dois pas utiliser la bonne instruction. Avez-vous une idée (simple au regard de mes faibles capacités) ?

Posté : 17 avr. 2008, 10:50
par steph29
en fait le but est de trouver si il y a un mauvais terme dans le message
la tu fais l'insert pour chaque occurence trouvée, il suffit juste de tester la validite du message
un petit exemple:

$valid_message=true; //message valide dans tout les cas (par defaut)
foreach($tableauMotsInterdits as $cle)  {   
     if (preg_match("/".$cle."/i", $message)){   
          $valid_message=false; //si on trouve un des mots le message est invalide
           break2; //on arrete les 2 boucles a la premiere occurence trouvée ;) => gain de temps
     }  
}

if ($valid_message) {
  echo "pas d'injure";
}

Posté : 17 avr. 2008, 11:01
par hakazizi
dans la ligne
$message = stripslashes(htmlentities($_POST["message"])); 
tu peut mettre
$message = stripslashes($_POST['message']); 
ce n'est pas la peine de mettre "htmlentities"

Posté : 17 avr. 2008, 11:08
par slec
Ca marche impec !!
Merci encore.