2012-12-03 19 views
7

私のサイトコードをmysql_ *関数を使ってPDOに変換しています。 PDOに関するPHPのドキュメントは、私のニーズにはっきりしていません。これは、使用する関数を提供しますが、さまざまなシナリオでそれらを説明するために詳細には入りません。PDOとMySQLの全文検索

基本的に、私は、MySQLの全文検索がありますはるかに長い

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

に実際の文を、これは、それは基本的に何をするかです。

私の質問は、これをPDOにどのように組み込むのですか?

あなたは場所マーカーの周りに引用符を使用するつもりはないので、あなたはAGAINST()関数でそれらを残しますか?私はそれらを含めるか?私はそれらを残して、ワイルドカード記号などに何が起こるのですか?

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

答えて

12

これは、残念ながら、クエリパラメータ(編集:各MySQLのブランチの最新のポイント・リリースでどうやらません、以下を参照)の使用に奇妙な例外です。

パターンはAGAINST()で、はクエリパラメータではなく定数文字列である必要があります。 SQL問合せの他の定数文字列とは異なり、ここでは問合せパラメータを使用できません。単純にMySQLの制限があるからです。

検索パターンをクエリに安全に補間するには、PDO::quote()関数を使用します。 PDOのquote()関数はすでに(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"); 

再@YourCommonSenseからのコメント:

そうだね、私はただのMySQL 5.5.31、5.1.68でこれをテストし、5.0.96(MySQLのサンドボックスは素晴らしいツールです。 )、これらのバージョンは動的SQLクエリのAGAINST()句でクエリパラメータを受け入れるようです。

私はまだ過去に存在していたコンフリクトを思い出しています。おそらく、各ブランチの最新のポイントリリースで修正されている可能性があります。例えば、私は、これらの関連のバグを見つける:プリペアドステートメント、MATCHおよびFULLTEXTとhttp://bugs.mysql.com/bug.php?id=3734

  • クラッシュまたは奇妙な結果:http://bugs.mysql.com/bug.php?id=14496
  • AGAINST()句でストアドプロシージャのパラメータを使用して

    • は常に同じ結果を返します。
    +0

    あなたの答えをありがとうございました、そして代替ソリューション:) –

    +2

    私はあなたが話しているこの「奇妙な」動作を再現することはできません。 '反対(?ブーリーンモードで)'は私のためにすべて正常に動作します。どのMySQLバージョンを使用していますか? –

    +0

    もちろん、エミュレーションモードはオフにされ、ダブルチェックされます。 –

    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(); 
    }