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

Résolu
neondoom33 -  
 neondoom33 -
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

  1. jordane45 Messages postés 30427 Date d'inscription   Statut Modérateur Dernière intervention   4 832
     
    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
    1. Utilisateur anonyme
       
      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
    2. jordane45 Messages postés 30427 Date d'inscription   Statut Modérateur Dernière intervention   4 832
       
      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
  2. neondoom33
     
    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
    1. jordane45 Messages postés 30427 Date d'inscription   Statut Modérateur Dernière intervention   4 832
       
      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
    2. neondoom33
       
      Effectivement, quel idiot ! le problème est désormais résolu.

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