8768 sujets

Développement web côté serveur, CMS

Pages :
Bonjour à tous,

J'ai un souci au niveau de mon code et je ne comprends pas l'origine de ce problème. En effet, j'ai créé une fonction PHP contenant un tableau avec une liste des mots interdits. Il s'agit d'un système de question/réponse. Si un client saisit un mot interdit dans sa réponse, je vérifie que ce mot ou expression est dans mon tableau. Si le mot existe et est interdit j'envoie un émail à l'administrateur pour le signaler, sinon j'enregistre la réponse et je l'affiche. Même dans le cas ou le mot est interdit j'enregistre quand même la réponse et c'est juste au niveau de l'affichage que je remplace le mot par des étoiles (***). L'envoie de mail c'est pour informer l'administrateur qu'un mot interdit a été saisi et lui permettre de le modérer ou de le supprimer.

Voici mon script :


// fonction mots interdits:
function motInterdit ($mot) {
        $mots = array(
              'mot 1',
              'mot 2',
              'mot 3'
        );
        $mot_remplacement = '******';
        $data = str_ireplace($mots, $mot_remplacement, $mot);
        return $data;
}


// requête d'insertion ici
/*.........*/

// select
$q = array('lastId'=>$lastId);
$sql = 'SELECT * FROM reponse WHERE reponse_id = :lastId';
$req = $db->prepare($sql);
$req->execute($q) or die(print_r($db->errorInfo()));

foreach ($req->fetchAll() as $data):
       $tab = nl2br(htmlspecialchars($data));
       $resTab = motInterdit ($tab);

       if (is_array(resTab) && in_array($tab, $resTab)) {
             // envoie de mail
             mail($to, $subject, $message, $headers);
       }
endforeach;

Je pense que mon problème c'est au niveau de la vérification si le mot interdit existe dans mon tableau. Car je n'arrive pas à envoyer mon mail. Mais je n'ai pas de problème au niveau du traitement de mon mail car si je fais un test d’envoi de mail avec un mot correcte ça fonctionne.

Merci pour votre aide !
Modifié par dinolam (20 Sep 2016 - 10:49)
var_dump($data) ne m'affiche rien.
J'ai juste ce message d'erreur et rien d'autre:

Array
(
[0] => 00000
[1] =>
[2] =>
)
1
au pire passe par un foreach classic :

foreach ($mots as $motARemplacer)
{
	if (strpos($motARemplacer, $mot) !== false)
	{
		$data = str_replace($motARemplacer, $mot_remplacement, $mot);	
	}
}



EDIT //


Pourtant moi ton code fonctionne...
 $mot = 'mot 2';
$mots = array(
              'mot 1',
              'mot 2',
              'mot 3'
        );
        $mot_remplacement = '******';
        $data = str_ireplace($mots, $mot_remplacement, $mot);
       var_dump($data);


Résultat :

string(6) "******"

Modifié par JENCAL (20 Sep 2016 - 11:56)
Le foreach que j'ai mis dans mon code c'est pour parcourir le résultat de ma requête select pour vérifier si un mot interdit a été saisi et ensuite envoyer un mail à l'admin. Mais je n'ai pas mis de foreach dans ma fonction motInterdit(). Car lors de l'enregistrement d'un mot interdit l'affichage se passe correctement (mot de remplacement). Mon problème c'est lors de l'envoie de mail après vérification si un mot existe dans ma fonction ou non.

Cdlt,
Modifié par dinolam (20 Sep 2016 - 12:02)
Ok

ton foreach me semble curieux,

mettre le fetchAll directement dedans :s ...
essaye de faire quelque chose du genre.
$results = $req->fetchAll();
foreach ($result as $data):
    print $data["name"] . "-" . $data["id"] ."<br/>"; // histoire de..
}
dinolam a écrit :
Ça ne change rien j'ai toujours la même erreur.


Après elle te dit quoi l'erreur exactement ?
error_reporting(E_ALL);
Modifié par JENCAL (20 Sep 2016 - 16:29)
Re,

Tout ce que j'ai comme erreur c'est ça :

Array
(
[0] => HY000
[1] => 206
[2] => General SQL Server error: Check messages from the SQL Server [206] (severity 16) [(null)]

[3] => -1
[4] => 16
)

Cdlt,
Modérateur
Tu as une erreur SQL.


$q = array('lastId'=>$lastId);
$sql = 'SELECT * FROM reponse WHERE reponse_id = :lastId';
$req = $db->prepare($sql);
$req->execute($q) or die(print_r($db->errorInfo()));

Et l’exécution de ton code s'arrête en cas d'erreur (or die).

Ton paramètre est mal nommé:
$q = array('lastId'=>$lastId);

devrait être:
$q = array(':lastId'=>$lastId);
Bonjour.

Les deux-points ne sont pas obligatoires... l'erreur ne doit pas venir de là.

Smiley smile

Edit : Cela dit, j'ai toujours créé le tableau de correspondance entre l'instruction 'prepare' et l'instruction 'execute'... pas sûre que cela ait une importance...

Edit : Je préfère utiliser bindValue que le tableau.
Modifié par Zelena (21 Sep 2016 - 14:23)
Apparement ton erreur c'est un problème de conversion, genre tu 'impossible de convertir int en string)

assure toi que reponse_id est bien du integer, et que ce que tu envois dans la requête sois également bien du integer. Si tu fais un var_dump($lastId) ça te dit quoi ?
Pour contextualiser à nouveau ce que je souhaite faire, j'ai un formulaire avec un champ texarea dans lequel un client peut saisir une réponse à une question posée précédemment. J'ai créé une fonction (motInterdit => code ci-dessus) qui contient elle-même un tableau avec une liste de mots ou expressions bannies. Quand une réponse est saisie je vérifie dans mon array qu'elle ne contient pas un des mots ou expressions. Si le test est positif j'envoie dans ce cas un mail à l'admin pour lui signaler et sinon j'envoie un autre mail à celui qui a posé sa question que elle a reçu de réponse. Dans tous les cas de figure j'enregistre la réponse dans la BD et les mots non désirés sont remplacés par des astérisque (***) pour l'affichage.


/ fonction mots interdits:
function motInterdit ($mot) {
        $mots = array(
              'mot 1',
              'mot 2',
              'mot 3'
        );
        $mot_remplacement = '******';
        $data = str_ireplace($mots, $mot_remplacement, $mot);
        return $data;
}
 
// Mon insert
/* ..............  */
 
// select
$q = array(':lastId'=>$lastId);
$sql = 'SELECT * FROM reponse WHERE reponse_id = :lastId';
$req = $db->prepare($sql);
$req->execute($q) or die(print_r($req->errorInfo()));
$rows = $req->fetchAll();
 
foreach ($rows as $row):
    $tab = nl2br(htmlspecialchars($row['reponse_message']));
    $resTab = motInterdit($tab);
 
    if (is_array($resTab) && in_array($tab, $resTab)) {
         // envoie de mail
         mail($to, $subject, $message, $headers);
    } else {
        // envoie de mail
        mail($to, $subject, $message, $headers);
    }
endforeach;


Dans le cas de saisie d'un mot normal = non interdit (condition else), l'envoie de mail marche bien et je récupère mes infos avec les mêmes requêtes précédentes. Donc c'est au niveau de cette condition qu'il y a un problème :

if (is_array($resTab) && in_array($tab, $resTab)) {}


Mon envoi de mail ne marche pas à ce niveau et que j'ai un message d'erreur. Hors dans le cas de else je n'ai pas de message d'erreur pourtant j'utilise la même requête, ce que je ne comprends pas.

Cdlt,
Modérateur
Zelena a écrit :
Les deux-points ne sont pas obligatoires... l'erreur ne doit pas venir de là.

Oh tiens je le découvre, bien que la doc ne le mentionne pas. Mais en effet PDO rajoute les : s'ils sont absents. Toutefois ceci n'est pas très clair et pourrait éventuellement disparaître dans une version ultérieure de PHP, la bonne pratique serait de les mettre quand même.

Quand à l'origine du bug, voir la réponse de JENCAL ci-dessus.
Bon je ne comprend plus où se situe ton problème.

dinolam a écrit :
l'envoie de mail marche bien et je récupère mes infos avec les mêmes requêtes précédentes.


Si t'es requêtes (ou ta requête, parce que j'en vois qu'une) fonctionnerais bien, tu n'aurais pas de
General SQL Server error: Check messages from the SQL Server [206] (severity 16) [(null)]


de plus je ne comprend pas ton nl2br () qui va ajouter des balise br dans ton string. du coup si ton mot interdit n'est pas du même format (avec la balise br) cela sera compliquer à comparer, mais du dois avoir t'es propres raisons pour l'avoir utilisé

Ensuite, il faudrait que fasse un var_dump de $resTab avant ta condition pour voir si il est pas null ou autres chose.
Modifié par JENCAL (21 Sep 2016 - 16:47)

// requête d'insertion
$message = $_REQUEST['message'];
$client_id = $_SESSION['client_id'];

$q = array(':message'=>$message, ':id'=>$client_id);
$sql = 'INSERT INTO reponse (reponse_message, reponse_date, client_id) VALUES (:message, GETDATE(), :id)';
$req = $db->prepare($sql);
$req->execute($q) or die(print_r($req->errorInfo()));

$lastId = (int) $db->lastInsertId();

// select
$q = array(':lastId'=>$lastId);
$sql = 'SELECT * FROM reponse WHERE reponse_id = :lastId';
$req = $db->prepare($sql);
$req->execute($q) or die(print_r($req->errorInfo()));
$rows = $req->fetchAll();


Et un
var_dump($lastId);
m'affiche int(6) dans le cas de la condition else mais avec if rien ne s'affiche.

L'erreur se situe au niveau de la condition if c'est là ou ma condition ne passe pas. Mais en cas de false (c'est-à-dire un mot non interdit) ça fonctionne. C'est là aussi que je bute parce que je ne comprends d’où vient le problème. Ce que je disais dans mes précédents messages j'utilise une seule requête pour les 2 conditions mais ça marche pour false pas pour if.

Le
var_dump($resTab);
affiche string(6) "coucou" en cas de false mais partie if il n'affiche rien en dehors du message d'erreur.

Cdlt,
Modifié par dinolam (21 Sep 2016 - 17:44)
@Jencal,

Tu disais je cite :

Je ne comprend pas non plus dans ta condition le in_array($tab, $resTab)

tu test si $tab (qui est le mot qui résultant de la requête sql) est présent dans le tableau $resTab qui est le tableau résultant de la function qui va remplacer le mot interdit par des étoiles.
Donc comment, après avoir remplacer le mot interdit par des étoile, peut-il (le mot résultant de la requête sql) être présent (encore?) dans le tableau de ta fonction? vu que l'a remplacer juste avant.


$tab est enregistré normalement dans la base de données. C'est juste au niveau de l'affichage qu'il est remplacé par des étoiles. Je pense c'est qui me bloque. Mais vu que mon remplacement par les étoiles se fait dans la fonction, comment puis-je remédier dans à ça dans ma condition ?

Cdlt,
Pages :