2009-11-23 5 views
40

J'essaie de faire une recherche par le biais de la classe PDO php (pilote mysql). J'ai la requête suivante travail avec le client MySQL (noms de tables changés pour protéger les innocents):PHP instruction préparée PDO - requête MySQL LIKE

SELECT hs.hs_pk, 
      hs.hs_text, 
      hs.hs_did, 
      hd.hd_did, 
      hd.hd_text, 
      hv.hv_text, 
      hc.hc_text 
FROM  hs 
LEFT JOIN hd 
ON  hs.hs_did = hd.hd_did 
LEFT JOIN hd 
ON  hd.hd_vid = hv.hv_id 
LEFT JOIN hc 
ON  hd.hd_pclass = hc.hc_id 
WHERE  hs.hs_text LIKE "%searchTerm%" 
LIMIT 25; 

Cela fonctionne comme un charme quel que soit le terme de recherche que j'utilise. Cependant, quand je passe à php, je ne peux pas l'obtenir pour retourner quelque chose. J'ai essayé plusieurs syntaxes différentes qui semblent logiques de travailler, mais rien que j'ai essayé fonctionne. voici mon code existant:

$handle = fopen('/foo/bar/test.log', 'w+'); 
fwrite($handle, "doSearch, with search term: $searchTerm\n"); 
$sql = 
'SELECT hs.hs_pk, 
      hs.hs_text, 
      hs.hs_did, 
      hd.hd_did, 
      hd.hd_text, 
      hv.hv_text, 
      hc.hc_text 
FROM  hs 
LEFT JOIN hd 
ON  hs.hs_did = hd.hd_did 
LEFT JOIN hd 
ON  hd.hd_vid = hv.hv_id 
LEFT JOIN hc 
ON  hd.hd_pclass = hc.hc_id 
WHERE  hs.hs_text LIKE :searchTerm 
LIMIT 25'; 

try { 
$dbh = new PDO('mysql:host=localhost;dbname=awdb', "user", "password"); 
fwrite($handle, "connected to DB\n"); 
$prep = $dbh->prepare($sql); 
$ret = $prep->execute(array(':searchTerm' => '"%'.$searchTerm.'%"')); 

while ($row = $prep->fetch(PDO::FETCH_ASSOC)) { 
    $i++; 
    $result[$i]['subText'] = $row['hs_pk']; 
    $result[$i]['subText'] = $row['hs_text']; 
    $result[$i]['subDid'] = $row['hs_did']; 
    $result[$i]['devDid'] = $row['hd_did']; 
    $result[$i]['devText'] = $row['hd_text']; 
    $result[$i]['vendorText'] = $row['hv_text']; 
    $result[$i]['classText'] = $row['hc_text']; 
} 
    $dbh = null; 
} 
catch (PDOException $e) { 
    print "Error!: " . $e->getMessage() . "<br/>"; 
    die(); 
} 

J'ai essayé ce qui suit aussi bien (clause SQL WHERE & prep-> exécuter des lignes sont tout ce changement):

WHERE hs.hs_text LIKE CONCAT(\'%\', ?, \'%\') 
$ret = $prep->execute(array($searchTerm)); 

WHERE hs.hs_text LIKE "%:searchTerm%" 
$ret = $prep->execute(array(':searchTerm' => $searchTerm)); 

WHERE hs.hs_text LIKE ":searchTerm" 
$ret = $prep->execute(array(':searchTerm' => '%'.$searchTerm.'%')); 

etc ...

+1

Il pourrait juste être un problème de transposition, mais vous n'avez pas joint votre déclaration sql - vous devez mettre une apostrophe (') à la fin de celui-ci. –

+0

C'était un problème de transposition. Si j'avais oublié le 'je suis sûr que PHP aurait complètement flippé, lol. Merci pour la réponse extrêmement rapide, cependant. – TIm

+1

Qu'est-ce que vous obtenez quand vous var_dump() $ dbh, $ prep et $ ret? Sont-ils des valeurs que vous attendez? Avez-vous essayé d'exécuter la même requête en utilisant la famille de fonctions mysql_ * pour la comparaison? – jkndrkn

Répondre

93
$ret = $prep->execute(array(':searchTerm' => '"%'.$searchTerm.'%"')); 

Ceci est faux. Vous n'avez pas besoin des guillemets doubles.

WHERE hs.hs_text LIKE ":searchTerm" 
$ret = $prep->execute(array(':searchTerm' => '%'.$searchTerm.'%')); 

Cela est également faux. Essayez avec:

$prep = $dbh->prepare($sql); 
$ret = $prep->execute(array(':searchTerm' => '%'.$searchTerm.'%')); 

Explication: Les instructions préparées ne font tout simplement pas une chaîne remplacer. Ils transportent les données complètement séparées de la requête. Les guillemets ne sont nécessaires que lors de l'intégration de valeurs dans une requête.

+0

Merci pour cette explication.Il ne peut pas résoudre celui-ci, mais je vais le classer dans ma mémoire pour une utilisation future. – TIm

+26

@Tlm vous devriez toujours accepter sa réponse. il répond à votre question comme prévu directement. Cela ne vous coûte rien d'accepter. –

-5

Eh bien, j'ai résolu celui-ci. Et franchement, je suis un idiot ... Merci à tous d'avoir vu ça et de donner de bons commentaires. Le problème était une faute de frappe dans un nom de table (que j'ai changé, donc personne ici ne serait capable de voir mon problème pour commencer ...). Les suggestions m'ont néanmoins amené à trouver le problème, alors merci Adam, Jerkkn et Troelskn.

Pour mémoire, la combinaison suivante fonctionne bien:

WHERE aw_hcl_subdevices.hs_text LIKE CONCAT(\'%\', ?, \'%\') 
$ret = $prep->execute(array($searchTerm)); 
+14

-1 Ce n'est pas la bonne façon de procéder. Vous ne devez pas * utiliser * CONCAT() pour trois littéraux de chaînes * statiques *, car cela vous ouvre à un type spécifique d'injection SQL (j'ai oublié le nom). –

+4

Dunno qui sont tous ces gens qui ont upvoted le commentaire ci-dessus, mais étrangement - aucun d'entre eux a réussi à nommer l'injection. Probablement parce qu'une telle «injection» n'a jamais existé. –

+0

Aimerait l'entendre de @ TheodoreR.Smith s'il est toujours là SO. [Plus spécifiquement sur cette question distincte] (http://stackoverflow.com/questions/22740375/why-should-you-not-use-concat-for-static-string-literals) – Prix

-2
$prep = $dbh->prepare($sql); 
$ret = $prep->execute(array('searchTerm' => $searchTerm)); 
+4

Cette année n'est pas terminée (à quel $ sql faites-vous référence?), Manque d'informations (comment faire ".. LIKE '% FOO%'" recherche?) Et manque de toute explication. Certains codes mis comme ceci n'est pas une réponse, IMO, est juste une chose hors contexte. – Redips77

Questions connexes