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

Petit nouveau ! | 8 Messages

16 avr. 2008, 18:57

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

Eléphant du PHP | 422 Messages

16 avr. 2008, 19:32

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)){  

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

16 avr. 2008, 19:32

Et là j'ai un beau message d'erreur !!
Qui est ? :)

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

16 avr. 2008, 19:42

À 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 ;)

Petit nouveau ! | 8 Messages

17 avr. 2008, 09:57

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 !!!";
	 }

Eléphant du PHP | 175 Messages

17 avr. 2008, 10:03

une accolade mal fermée?

Petit nouveau ! | 8 Messages

17 avr. 2008, 10:42

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) ?

Eléphant du PHP | 175 Messages

17 avr. 2008, 10:50

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";
}

Mammouth du PHP | 558 Messages

17 avr. 2008, 11:01

dans la ligne
$message = stripslashes(htmlentities($_POST["message"])); 
tu peut mettre
$message = stripslashes($_POST['message']); 
ce n'est pas la peine de mettre "htmlentities"

Petit nouveau ! | 8 Messages

17 avr. 2008, 11:08

Ca marche impec !!
Merci encore.