2012-12-03 3 views
7

Je convertis tout le code de mes sites en utilisant les fonctions mysql_ * pour PDO. La documentation PHP sur PDO n'est pas claire pour mes besoins. Il vous donne les fonctions à utiliser, mais ne va pas dans les détails pour les expliquer dans différents scénarios.PDO et MySQL Recherche plein texte

Fondamentalement, j'ai une recherche mysql du texte intégral:

$sql = "SELECT ... FROM search_table WHERE MATCH(some_field) AGAINST ('{$searchFor}*' IN BOOLEAN MODE)"; 

Les déclarations réelles beaucoup plus, mais c'est ce qu'il fait essentiellement.

Ma question est, comment pourrais-je l'intégrer dans PDO?

Je sais que vous n'êtes pas censé utiliser des guillemets autour du marqueur de lieu, alors laissez-les dans la fonction AGAINST()? Est-ce que je les inclut? Si je les laisse, qu'arrive-t-il au symbole générique, etc.?

$sql = $this->db->prepare("SELECT ... FROM search_table WHERE MATCH(some_field) AGAINST(:searchText IN BOOLEAN MODE"); 
$sql->bindValue(':searchText', $searchFor . '*'); 

Répondre

12

C'est malheureusement une exception bizarre à l'utilisation des paramètres de la requête (modifier: mais apparemment pas dans le point le plus récent de la libération de chaque branche MySQL, voir ci-dessous).

Le motif AGAINST()doit être être une chaîne constante, pas un paramètre de requête. Contrairement à d'autres chaînes de caractères constantes dans les requêtes SQL, vous ne pouvez pas utiliser un paramètre de requête ici, simplement en raison d'une limitation dans MySQL.

Pour interpoler des motifs de recherche dans des requêtes en toute sécurité, utilisez la fonction PDO::quote(). Notez que la fonction quote() de PDO ajoute déjà les délimiteurs de guillemets (contrairement à mysql_real_escape_string()).

$quoted_search_text = $this->db->quote('+word +word'); 

$sql = $this->db->prepare("SELECT ... FROM search_table 
    WHERE MATCH(some_field) AGAINST($quoted_search_text IN BOOLEAN MODE"); 

Re commentaire de @YourCommonSense:

Vous avez raison, je viens sur ce MySQL testé 5.5.31, 1.5.68 et 5.0.96 (MySQL Sandbox est un merveilleux outil), et il semble que ces versions acceptent les paramètres de requête dans la clause AGAINST() d'une requête SQL dynamique. J'ai toujours un souvenir d'un conflit existant dans le passé. Peut-être a-t-il été corrigé dans le dernier point-release de chaque branche. Par exemple, je trouve ces bugs liés:

+0

Merci beaucoup pour votre réponse et solution de rechange :) –

+2

je ne peux pas reproduire ce comportement « bizarre » vous parlez. 'CONTRE (? EN MODE BOOLEAN)' fonctionne bien pour moi. Quelle version de Mysql utilisez-vous? –

+0

Bien sûr, le mode d'émulation est désactivé et revérifié. –

0
$sql = "SELECT * FROM tablename WHERE MATCH (fieldname) AGAINST (:searchstr IN BOOLEAN MODE) LIMIT {$per_page} OFFSET {$pg_offset}"; 

try { 
    $database->prepare($sql); 
    $database->bindParam(':searchstr', $search); 
    $database->execute(); 
    $result_array = $database->fetch_array($sql); 
} catch (Exception $e) { 
    echo $e->getMessage(); 
}