Requete préparée + WHERE IN / OR = la galère

Résolu/Fermé
neondoom33 - 22 mai 2018 à 01:00
 neondoom33 - 22 mai 2018 à 14:09
Bonjour,

Comment réussire une requete requete préparée avec WHERE IN OU OR comme condition ? j'ai beau me creuser la tête je trouve pas de solution !! PS : Je ne peux pas faire ma requete a la "dur" vu que je ne sais pas a l'avance combien de IN ou OR il va y avoir dans la requete !


$keywords = explode(',', $tags);
$like = "";

foreach($keywords as $keyword) {
$keyword = trim($keyword);
$like.= "'".$keyword."',";
}

$like = substr($like, 0, strlen($like) - 1);
$data = array('tag_name'=>$like);
$req = $DB->query( "SELECT tag_id FROM tag_list WHERE tag_name IN (tag_name)",$data);



public function query($sql,$data=array()){
$req = $this->connexion->prepare($sql);
$req->execute($data);

return $req->fetchAll(PDO::FETCH_OBJ);
}


merci d'avance, bonne soirée!

2 réponses

jordane45 Messages postés 38136 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 16 avril 2024 4 647
Modifié le 22 mai 2018 à 11:42
Bonjour,


Déjà... n'oublie pas d'activer la gestion des erreurs PDO.
(et de mettre ta requête dans un try/catch )
https://forums.commentcamarche.net/forum/affich-37584941-php-pdo-gerer-les-erreurs

Ensuite, concernant ton IN ... soit je mettrai directement les valeurs dans la chaine sql
$keywords = explode(',', $tags);

$in = join("','", $keywords);
$sql = "SELECT tag_id FROM tag_list WHERE tag_name IN ('".$in."')"
$req = $DB->query( $sql , NULL);


Soit j'essaierai de mettre chaque valeur dans un array de data
$keywords = explode(',', $tags);

$tmpDatas = array();
$datas = array();

$i = 0;
foreach($keywords as $D){
 $i++;
 $tmpDatas[] = ':tag'.$i;
 $datas[':tag'.$i] = $D;  
}

$in = join(',' , $tmpDatas);

$sql = "SELECT tag_id FROM tag_list WHERE tag_name IN (".$in.")"
$req = $DB->query( $sql , $datas);



1
Utilisateur anonyme
22 mai 2018 à 11:26
Bonjour

La première méthode proposée par Jordane (que je salue au passage) est à proscrire si tes $keywords viennent d'une saisie de l'utilisateur. Les données ne sont pas échappées, que va-t-il se passer si elles contiennent des apostrophes ?

Et pour la seconde méthode, ce serait plus logique d'initialiser $tmpDatas= array(); plutôt qu'une chaîne vide, non ?
0
jordane45 Messages postés 38136 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 16 avril 2024 4 647
22 mai 2018 à 11:42
ce serait plus logique d'initialiser $tmpDatas= array(); plutôt qu'une chaîne vide, non ?

Oui une erreur de copier/coller de ma part.
Je corrige dans le code initiale.
0
Salut jordane,

Tout simplement génial, la deuxième solution marche du tonerre, j'ai bien fait de demander car j'aurais jamais pu trouver ça tout seul !

Par contre j'ai remarqué un truc assez embêtant si il y a un espace entre un tags et une virgule exemple : tag1 , tag2,tag3 seul le premier tag et le troisieme tag seront pris en compte.

Est ce possible d'avoir les saisie :< tag1,tag2,tag3> et <tag1 , tag2 , tag3> correct ?

bonjour le père, bien vu en effet les saisies viennent majoritairement des utilisateurs , c'est pour cette raison que je voulais absolument faire une requete préparé afin d'eviter les injections !
0
jordane45 Messages postés 38136 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 16 avril 2024 4 647
22 mai 2018 à 13:54
Il te suffit de faire des "trim" pour virer les espaces superflus.
foreach($keywords as $D){
 $i++;
 $tmpDatas[] = ':tag'.$i;
 $datas[':tag'.$i] = trim($D);  
}
0
Effectivement, quel idiot ! le problème est désormais résolu.

Un énorme merci pour votre aide, bonne journée! :)
0