PDO - $query.= + WHERE IN

Résolu/Fermé
Flamingo_ Messages postés 23 Date d'inscription lundi 23 septembre 2013 Statut Membre Dernière intervention 25 février 2015 - Modifié par Flamingo_ le 13/02/2015 à 10:35
 Utilisateur anonyme - 14 févr. 2015 à 14:16
Bonjour,

Est-ce que quelqu'un sait comment faire un WHERE IN avec pdo dans la config suivante ? SVP - Merci beaucoup.

 <select multiple="multiple" name="secteur_searched[]" >
 <option value="1">Accueil - Secrétariat - Fonctions Administratives</option>
 <option value="2">Achats - Juridique - Qualité; - RH - Direction</option>
     etc...
 </select> 

<input type="checkbox" name="type_de_contrat[]" value="CDI" >      
<input type="checkbox" name="type_de_contrat[]" value="CDD" > 


try{
$query =  "SELECT * FROM interim_job_offers j 
          JOIN villes v ON v.ville_id =j.job_ville  "; 
 $where = array();
 $param = array();
 
 if (!empty($_REQUEST['secteur_searched']) AND is_array($_REQUEST["secteur_searched"]) ) // esta parte
    {
     $where[] = "j.job_secteur IN (:job_secteur)";
     $param[":job_secteur"] = "'".implode("','",    $_REQUEST['secteur_searched'])."'";
    } 

 if(!empty($_REQUEST['type_de_contrat']) AND count($_REQUEST['type_de_contrat']) > 0 ) // y esta
   {
    $where[] = "j.job_contrat IN (:job_contrat)";
    $param[":job_contrat"] = "'".implode("','", $_REQUEST['type_de_contrat'])."'";
   }    
   
if (!empty($where)) 
   {$query.= ' WHERE ' . implode(' AND ', $where); 
   }

 $query.= " ORDER BY j.job_date_insertion DESC"; 
 
$sth =$mInterim ->prepare($query); 
$sth->execute($param);

4 réponses

jordane45 Messages postés 38241 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 17 septembre 2024 4 689
Modifié par jordane45 le 13/02/2015 à 11:29
Bonjour,

Déjà.. pas besoin d'ajouter des quotes autour de l'implode...
 $param[":job_secteur"] = implode("','",    $_REQUEST['secteur_searched']);


Ensuite.. quand tu ne trouves pas d'où vient le souci.. commence par faire des echo/print de tes variables pour savoir ce qu'elles contiennent...

try{
//-------------------------------
// Le temps des tests :
//-------------------------------
echo "<br>Variables REQUEST <br>";
print_r($_REQUEST);
//-------------------------------

$where = array();
$param = array();
$query =  "SELECT * 
               FROM interim_job_offers j 
               JOIN villes v ON v.ville_id =j.job_ville  "; 

 
 if (!empty($_REQUEST['secteur_searched']) AND is_array($_REQUEST["secteur_searched"]) ) // esta parte
    {
     $where[] = "j.job_secteur IN (:job_secteur)";
     $param[":job_secteur"] = implode(",",    $_REQUEST['secteur_searched']);
    } 

 if(!empty($_REQUEST['type_de_contrat']) AND count($_REQUEST['type_de_contrat']) > 0 ) // y esta
   {
    $where[] = "j.job_contrat IN (:job_contrat)";
    $param[":job_contrat"] = implode(",", $_REQUEST['type_de_contrat']);
   }    
   
if (!empty($where)) {
    $query.= ' WHERE ' . implode(' AND ', $where); 
 }

 $query.= " ORDER BY j.job_date_insertion DESC"; 
 

//-------------------------------
// Le temps des tests :
//-------------------------------
echo "<br>QUERY <br>";
print_r($query);

echo "<br>PARAM<br>";
print_r($param);
//-------------------------------


$sth =$mInterim ->prepare($query); 
$sth->execute($param);




Cordialement,
Jordane
0
Flamingo_ Messages postés 23 Date d'inscription lundi 23 septembre 2013 Statut Membre Dernière intervention 25 février 2015 1
Modifié par Flamingo_ le 13/02/2015 à 11:49
Bonjour :)

Est-ce que tu as déjà essayé WHERE IN avec pdo dans cette config?

Avec mysql je suis d'accord, pas besoin de quotes sur un implode pour WHERE IN.
Dans ce cas précis, avec PDO, je ne sais pas faire. J'ai déjà fait un implode classique, (ma première idée), mais ça ne fonctionne pas.

Print_r / echo/var_dump, je l'ai fait sur toutes mes vars.

Le problème c'est que selon ce que j'ai lu/vu/entendu, WHERE IN de pdo n'accepte pas un array, mais qu'une seule valeur à la fois...

Regarde ce lien https://stackoverflow.com/questions/920353/can-i-bind-an-array-to-an-in-condition
Est-ce que tu saurais appliquer ce qui est expliqué à mes $params ?? Moi non !!! malgré des jours de recherches


*


*

Sinon est-ce qu'il y aune autre manière selon mes conditions if(!empty), d'éviter de faire execute($param)? Je préférais faire execute() et bindParam, mais je ne suis sur pdo que depuis quelques jours donc je ne sais pas si c'est possible et comment faire - pas trouvé d'exemple lorsque if(!empty) {$query.= .... )

Merci beaucoup
0
Flamingo_ Messages postés 23 Date d'inscription lundi 23 septembre 2013 Statut Membre Dernière intervention 25 février 2015 1
Modifié par Flamingo_ le 13/02/2015 à 12:02
Sinon, un autre exemple trouvé sur internet:
$list_id = array_filter(array_map('intval', $_POST['del']));
if(count($list_id) <> 0)
  $selection_delete = $bdd->query('SELECT pseudo_note, id_note FROM notes_membre WHERE id_note IN('.implode(',', $list_id).')');


Sais-tu l'appliquer à mes conditions ?

Lorsque je tente :
 if(!empty($_REQUEST['secteur_searched']) AND is_array($_REQUEST["secteur_searched"]) ) {
 $secteur= array_filter(array_map('intval', $_REQUEST["secteur_searched"]));
   if(count($secteur) <> 0 )     
    $where[] = "j.job_secteur IN (:job_secteur)";
    $param[":job_secteur"] = "'.(implode(',', $secteur)).'"; 
   }

J'ai un bel array_to_string conversion à la ligne de $param[":job_secteur"]....
0
jordane45 Messages postés 38241 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 17 septembre 2024 4 689
13 févr. 2015 à 13:16
Un INPLODE te retourne une STRING ... donc pas besoin d'y ajouter des quotes !
0
Flamingo_ Messages postés 23 Date d'inscription lundi 23 septembre 2013 Statut Membre Dernière intervention 25 février 2015 1
13 févr. 2015 à 13:19
je les ai enlevées les quotes (les avais mises pour test) et ça me donne array_to_string conversion !
0
jordane45 Messages postés 38241 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 17 septembre 2024 4 689
13 févr. 2015 à 13:44
Bon.. je viens de tester....
Avec les quotes.. c'est mieux en effet...

<?php

if($_REQUEST){
//-------------------------------
// Le temps des tests :
//-------------------------------
echo "<br>Variables REQUEST <br>";
print_r($_REQUEST);
//-------------------------------



$where = array();
$param = array();
$query =  "SELECT * 
          FROM interim_job_offers j 
          JOIN villes v ON v.ville_id =j.job_ville  "; 

 
 if (!empty($_REQUEST['secteur_searched']) AND is_array($_REQUEST["secteur_searched"]) ) // esta parte
    {
     $where[] = "j.job_secteur IN (:job_secteur)";
     $param[":job_secteur"] = "'". implode("','",    $_REQUEST['secteur_searched']) . "'";
    } 

 if(!empty($_REQUEST['type_de_contrat']) AND count($_REQUEST['type_de_contrat']) > 0 ) // y esta
   {
    $where[] = "j.job_contrat IN (:job_contrat)";
    $param[":job_contrat"] = "'" . implode("','", $_REQUEST['type_de_contrat']) . "'";
   }    
   
if (!empty($where)) {
    $query.= ' WHERE ' . implode(' AND ', $where); 
 }

 $query.= " ORDER BY j.job_date_insertion DESC"; 
 

//-------------------------------
// Le temps des tests :
//-------------------------------
echo "<pre>";
echo "<br>QUERY <br>";
print_r($query);

echo "<br>PARAM<br>";
print_r($param);
echo "</pre>";
//-------------------------------
	
$sth =$mInterim ->prepare($query); 
$sth->execute($param);

}

?>



Que te donnes ce code ci ?
Que t'affichent les Echo / Print que j'y ai mis ?
As tu toujours ton message d'erreur ?

0
Flamingo_ Messages postés 23 Date d'inscription lundi 23 septembre 2013 Statut Membre Dernière intervention 25 février 2015 1
Modifié par Flamingo_ le 13/02/2015 à 14:35
Ce code-là ne me retourne rien...
Ou sinon à présent une erreur de syntaxe dans WHERE IN, mais ça je m'en doutais..

EDIT sur cette ligne --> Prêt à péter un câble ?

SInon :

QUERY : select ... WHERE j.job_secteur IN (:job_secteur)

PARAM
Array
(
[:job_secteur] => '1','2','3'
)

0
Flamingo_ Messages postés 23 Date d'inscription lundi 23 septembre 2013 Statut Membre Dernière intervention 25 février 2015 1
13 févr. 2015 à 14:13
Ce qui était simple avec mysql est hyper compliqué voir impossible (?) avec PDO. Personne n'a su trouver la réponse (ou du moins me la souffler), dans le cas de if (!empty) {$query.= WHERE IN)
0
Flamingo_ Messages postés 23 Date d'inscription lundi 23 septembre 2013 Statut Membre Dernière intervention 25 février 2015 1
13 févr. 2015 à 14:52
Tu utilises quoi d'habitude pour interroger une bdd?
Est-ce que ce ne serait pas plus simple avec mysqli?
Merci
0
jordane45 Messages postés 38241 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 17 septembre 2024 4 689
13 févr. 2015 à 16:24
Je pense que le souci vient de l'utilisation de ton param....
Après relecture de ton code.. je ne vois nul part de liaison entre tes variables et ta requête....
Selon moi.. il manque le bindParam;;
https://www.php.net/manual/fr/pdostatement.bindparam.php
0
Flamingo_ Messages postés 23 Date d'inscription lundi 23 septembre 2013 Statut Membre Dernière intervention 25 février 2015 1
13 févr. 2015 à 16:49
Au départ, j'avais fait :
if (!empty($_REQUEST['job_searched']))
     { $job_searched =$_REQUEST['job_searched'];
	$query.= " j.job_intitule=:job_intitule AND";
     }

 $query.= substr_replace($query, "", -3, 3);
                                
 $query.= " ORDER BY j.job_date_insertion DESC"; // LIMIT :start,:per_page ");
								
if (isset($job_searched)) $query->bindParam(':job_intitule', $job_searched);
if (isset($secteur_searched))  $query->bindParam(':job_secteur', $secteur_searched);

// etc
 $query->bindParam(':start', $start, PDO::PARAM_INT);
 $query->bindValue(':per_page', (int) trim($_REQUEST['afficher_x_resultats']), PDO::PARAM_INT);

$query->execute();


et j'avais des erreurs. Donc j'ai posé la question "comment on fait avec pdo ?" et on m'a dit que vu ma config -> if (!empty) { select..}, il fallait créer un array $param[':placeholder"]=$value, sans typage, et ce pour chaque vérif, et terminer par execute( $param).

Moi j'en sais rien, je débute avec pdo, et je teste tout ce que je trouve sur internet (énormément de recherche... internationales même), Donc je demande à qui sait le faire de bien vouloir m'expliquer/me montrer/corriger.

Mon code de départ, te semble comment ?

Thank u
0
Utilisateur anonyme
13 févr. 2015 à 20:24
Bonjour

Puisque chaque marqueur dans une requête PDO ne peut remplacer qu'UNE SEULE valeur, pas question de mettre un simple "j.job_secteur IN (:job_secteur)" : il faut obligatoirement générer une liste de marqueurs de même longueur que la liste que tu veux mettre dedans. Personnellement, j'utilise le ? qui m'évite d'avoir à imaginer des noms.
Pour créer une liste de "?", je crée d'abord un tableau de "?" avec array_fill, puis je les transforme en chaîne avec implode :
implode (',',array_fill(0,count(($_REQUEST['secteur_searched'])),'?'));
D'autre part, je mets les tableaux bout à bout avec array_merge.

$query =  "SELECT * FROM interim_job_offers j
          JOIN villes v ON v.ville_id =j.job_ville  ";
 $where = "";
 $param = array();

 if (!empty($_REQUEST['secteur_searched']) AND is_array($_REQUEST["secteur_searched"]) AND COUNT($_REQUEST["secteur_searched"])>0 ) // esta parte
    {
     $where = "j.job_secteur IN (".implode (',',array_fill(0,count($_REQUEST['secteur_searched']),'?')).") ";
     $param =   $_REQUEST['secteur_searched'];
    }

 if(!empty($_REQUEST['type_de_contrat']) AND is_array($_REQUEST["type_de_contrat"]) AND count($_REQUEST['type_de_contrat']) > 0 ) // y esta
   {
    $where .= (empty($where) ? '':' AND ')."j.job_contrat IN (".implode (',',array_fill(0,count($_REQUEST['type_de_contrat']),'?')).") ";
    $param = array_merge($param, $_REQUEST['type_de_contrat']);
   }

if (!empty($where))
   {$query.= ' WHERE ' . $where;
   }

 $query.= " ORDER BY j.job_date_insertion DESC";

$sth =$mInterim ->prepare($query);
$sth->execute($param);
?>
0
Flamingo_ Messages postés 23 Date d'inscription lundi 23 septembre 2013 Statut Membre Dernière intervention 25 février 2015 1
Modifié par Flamingo_ le 13/02/2015 à 21:50
Bonsoir,
Vous avez mis fin à 5 jours de souffrance ! :DDDD fiesta !!

On n'était pas loin : j'avais un très bon feeling avec array_fill et $param tout court, mais je n'aurais pas pensé à mettre un array_merge sur $_REQUEST.
il fallait savoir la formulation exacte... vue nulle part sur internet et pourtant j'en ai parcouru des centaines de pages...

MERCI MILLE FOIS du sauvetage et merci aussi à Jordane ;). MERCI BEAUCOUP
Vous imaginez pas le bien que ça fait d'avoir la solution ! MERCI
(Formule à enregistrer de suite !)

Vous m'avez rendu le sourire, grand comme ça !!!!!
0
Utilisateur anonyme > Flamingo_ Messages postés 23 Date d'inscription lundi 23 septembre 2013 Statut Membre Dernière intervention 25 février 2015
Modifié par le père. le 13/02/2015 à 22:40
il fallait savoir la formulation exacte... vue nulle part sur internet
Non, c'est absurde, il n'y a pas à connaître des centaines de formules magiques pour des tas de cas différents. Je n'ai fait que décomposer ce qu'on voulait obtenir jusqu'à arriver aux fonctions standard du PHP : ça ne demande aucune astuce et surtout pas de connaître de grandes listes de cas particuliers. Je n'avais jamais fait de 'WHERE IN' de longueur variable avant.
Il n'est pas question de "feeling" avec array_fill : on y vient naturellement quand on veut un tableau qui répète plusieurs fois la même chose. Et il ne ne faut aucune imagination pour utiliser array_merge sur $_REQUEST : on avait besoin de mettre deux tableaux bout à bout, et c'est cette fonction qui sert à ça en PHP.
0
Flamingo_ Messages postés 23 Date d'inscription lundi 23 septembre 2013 Statut Membre Dernière intervention 25 février 2015 1
Modifié par Flamingo_ le 14/02/2015 à 10:09
Quand on attaque quelque chose de nouveau (pdo en ce qui me concerne) et qu'on ne sait pas comment faire à un certain niveau, on cherche. Et quand on cherche : on trouve une dizaine/vingtaine de formulations différentes qui ne s'appliquaient pas au cas auquel est confronté. D'autres vous indiquent des formulations qui s'avèrent erronées. Votre raisonnement sur array_merge $_REQUEST coule de source quand on est expérimenté. Pour un débutant c'est autre chose....
0
Utilisateur anonyme > Flamingo_ Messages postés 23 Date d'inscription lundi 23 septembre 2013 Statut Membre Dernière intervention 25 février 2015
14 févr. 2015 à 14:16
J'ai débuté aussi (amateur autodidacte) et j'ai toujours fait comme ça.
Le problème général que je vois sur ce forum, c'est que les gens cherchent à tout prix à obtenir des résultats et préfèrent apprendre des recettes qui ne leur serviront que dans un cas particulier, plutôt que des principes qui leur serviraient dans tous les cas. Ces principes, c'est d'abord l'apprentissage des bases des langages. En PHP par exemple, je n'hésite pas à dire que 95% des intervenants sur ce forum - helpeurs compris - ne maîtrisent pas la manipulation des chaînes, ce qui est pourtant un point très fondamental. Ensuite, c'est le recours au manuel, pas seulement pour voir qu'une fonction a un rapport avec ce qu'on veut, surtout pour vérifier scrupuleusement et non pas superficiellement, quel est son rôle, ses paramètres, ses restrictions et éventuellement quelles fonctions voisines pourraient être intéressantes.
Bon, j'ai déjà été trop bavard, je ne vais pas refaire le monde.
Bonne chance pour la suite.
0