1. ホーム
  2. php

[解決済み] Wordpress wpdb->prepare sql string from form

2022-02-14 13:16:25

質問

私は現在、外部のxmlフィードを格納するためにカスタムwordpressテーブルを使用しており、この情報は、いくつかのオプションで基本的なHTMLフォームでフィルタリングできるようにする必要があります。

を使用して文字列を構築するのがベストな方法です。 wpdb->prepare ? 私はページネーションに下記を使用しており、$user_queryは現在、以下のように設定されています。 $user_query .= "AND クエリ1 LIKE $query1 "; などです。

しかし、この場合、2番目のパラメータを経由しないので、問題が生じる可能性があります。 %d , $variable などです。

//Get Results
$results = $wpdb->get_results(
    $wpdb->prepare("SELECT * FROM `feed` WHERE `price` != 0 $user_query  LIMIT %d,
       %d", $offset, $items_per_page, OBJECT)
  );

以上、ご理解いただけたでしょうか。私はフォームからSQLクエリを構築しようとしているだけです。 $_GET の値をSQLインジェクションの問題なく使用することができます。

ありがとうございました。

解決方法は?

を呼び出すことができます。 $wpdb->prepare を部分的なクエリで使用することができます。

$user_query = $wpdb->prepare('AND query1 LIKE %s', $query1);

を呼び出すこともできます。 esc_sql は、ユーザー入力に対して直接サニタイズ処理を行います。

また、LIKE式は別途エスケープする必要があります。

https://codex.wordpress.org/Class_Reference/wpdb/esc_like

$wpdb->esc_like は、ライク表現に特有の文字(%, \, _)をエスケープしますが、それ以外のエスケープは行いません。この場合でも prepare または esc_sql のような式をエスケープした後。

更新:コメントにあったこの例を使って。

$user_query = $_GET['query1']; 
$user_query2 = $_GET['query2']; 

$user = $wpdb->prepare('AND query1 = %s ', $user_query); 
$user2 = $wpdb->prepare('AND query2 = %s ', $user_query2); 

$results = $wpdb->get_results( $wpdb->prepare('SELECT * FROM test WHERE price != 0' . $user . $user2 . 'LIMIT 20') );   

ここで、クエリを部分的に構築する意味はありません。このようにクエリを構築すればよいのです。

$query = 'SELECT * FROM test 
            WHERE price != 0 
                AND query1 = %s 
                AND query1 = %s 
            LIMIT 20';
$results = $wpdb->get_results( $wpdb->prepare($query, $user_query, $user_query2) ); 

例として、ユーザークエリーはオプションであると仮定します。その場合は、パラメータが提供される場合のみ、WHERE条件を別途用意する必要があります。

$query = 'SELECT * FROM test 
            WHERE price != 0';

if($user_query) {
    $cond = $wpdb->prepare(' AND query1 = %s', $user_query);
    $query .= $cond;
}

if($user_query2) {
    $cond = $wpdb->prepare(' AND query2 = %s', $user_query2); 
    $query .= $cond;
}

$query .= ' LIMIT 20';
$results = $wpdb->get_results( $query );

に渡すときに、クエリに対して prepare を呼び出す必要がないことに注意してください。 get_results すべてのユーザー入力はすでにサニタイズされているからです。