1

phpを使用して生成されたSQLクエリがあります。検索語に一致するフィールドを持つレコードと、検索語に一致する他のテーブルに関連するレコードがあるレコードの代理キーを返します。

テーブルを1つに結合してから、別の関数を使用して、テーブルに含まれる列のリストを取得します(継続的なメンテナンスを減らすために、phpコードを書き直さずにテーブルに追加できるようにしたい)。

次に、このコードを使用します

foreach ($col_array as $cur_col) {
    foreach ($search_terms_array as $term_searching) {
        $qry_string.="UPPER(";
        $qry_string.=$cur_col;
        $qry_string.=") like '%";
        $qry_string.=strtoupper($term_searching);
        $qry_string.="%' or ";
    }
}

残りのクエリ文字列を生成するには

select tbl_sub_model.sub_model_sk from tbl_sub_model inner join [about 10 other tables]

    where [much code removed] or UPPER(tbl_model.image_id) like '%HONDA%' or
 UPPER(tbl_model.image_id) like '%ACCORD%' or UPPER(tbl_badge.sub_model_sk) like '%HONDA%'
 or UPPER(tbl_badge.sub_model_sk) like '%ACCORD%' or UPPER(tbl_badge.badge) like '%HONDA%'
 or UPPER(tbl_badge.badge) like '%ACCORD%' group by tbl_sub_model.sub_model_sk

それは私がやりたいことをしますが、SQLインジェクションに対して脆弱です。私はそれを防ぐためにmysql_*コードをpdoに置き換えていますが、これをどのように保護するかは私を超えています。

だから私の質問は、これらすべてのテーブルを安全な方法で検索するにはどうすればよいですか?

4

2 に答える 2

0

データベースに検索語を大文字にし、'%'ワイルドカードで装飾するように要求するソリューションを次に示します。

$parameters = array();
$conditions = array();
foreach ($col_array as $cur_col) {
    foreach ($search_terms_array as $term_searching) {
        $conditions[] = "UPPER( $cur_col ) LIKE CONCAT('%', UPPER(?), '%')";
        $parameters[] = $term_searching;
    }
}

$STH = $DBH->prepare('SELECT fields FROM tbl WHERE ' . implode(' OR ', $conditions));
$STH->execute($parameters);

ノート:

  1. PHP が strtoupper() を呼び出すのではなく、MySQL がユーザーの検索用語で UPPER() を呼び出せるようにし
    ました。すべての正規化は 1 か所で行われ、使用の瞬間に可能な限り近くなります。
  2. CONCAT() は MySQL 固有
    ですが、質問にタグを付けたように[mysql]、それはおそらく問題ではありません。
  3. このクエリは、元のクエリと同様に、インデックス作成に反対します。
于 2012-11-16T19:49:37.287 に答える
-1

パラメータを保持するために配列を使用して、このようなことを試してください。LIKE %?% はクエリ文字列では機能しないため、用語の前後に % が追加されていることに注意してください。PHP マニュアル

    //Create array to hold $term_searching
    $data = array();
    foreach ($col_array as $cur_col) {
        foreach ($search_terms_array as $term_searching) {
            $item = "%".strtoupper($term_searching)."%";//LIKE %?% does not work
            array_push($data,$item) 
            $qry_string.="UPPER(";
            $qry_string.=$cur_col;
            $qry_string.=") LIKE ? OR";
        }
}
$qry_string = substr($qry_string, 0, -3);//Added to remove last OR

$STH = $DBH->prepare("SELECT fields FROM table WHERE ". $qry_string);//prepare added 
$STH->execute($data);  

編集

$qry_string = substr($qry_string, 0, -3)ORの最後の出現を削除するために追加され、にprepare追加されました$STH = $DBH->prepare("SElECT fields FROM table WHERE". $qry_string)

于 2012-11-16T15:29:35.803 に答える