web-dev-qa-db-ja.com

$ wpdb-> prepareは複数回実行できるプリペアドステートメントを作成しないのですか?

構文から疑問に思う

$sql = $wpdb->prepare( 'query' [, value_parameter, value_parameter ... ] )

単純なエスケープ値は、準備されたステートメントを狂わせることはなく、複数回実行したときにパフォーマンス上の利点があるため、パラメータが異なります。

一見すると、値はオプションなので、準備した後に設定できますか?それ、どうやったら出来るの?

5
JM at Work

$wpdb-preparesprintfvsprintfのように動作します。最初の引数は常にフォーマット文字列です。

使用できる形式指定子は%s%dだけです。その他私は一度もテストしたことがありませんが、コーデックスに従って解析エラーを引き起こす可能性があります。クエリではでリテラルをエスケープする必要があります。例:%%

実行前の引数の数がわかっている場合にのみ可能なsprintfのように使用すると、引数の数をフォーマット文字列のフォーマット指定子の数と一致させることができます。

E.g: $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}_votes WHERE post_id = %d AND username = %s", $post_id, $username );

ランタイムまでの引数の数がわからない場合は、vsprintfのように使用する必要があります。この場合、最初の引数はフォーマット指定子になりますが、2番目の引数は配列になります。

E.g: $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}_votes WHERE post_id = %d AND username = %s", array( $post_id, $username ) );

$wpdb->prepareはSQL QUERY文字列を返します。この文字列は好きなだけ実行できます。

上記の例では、結果のクエリは次のようになります。SELECT * FROM wp_votes WHERE post_id = 747 AND username = 'cooluser'

4

言うまでもなく、開発者は "prepared"文がデータベース内で "prepared"を意味することを期待しています

そのステートメントが何度も使用される可能性があるかどうかは、サブ質問で尋ねられました。 wpdb-> prepareは実際には文を "準備"しません。入力をサニタイズするだけです。これはwordpress/wp-includes/wp-db.phpにあります。 prepare関数を探すと、それは通常の非プリペアドクエリを作成しているだけであることがわかります。

$query = array_shift($args);
$query = str_replace("'%s'", '%s', $query);
$query = str_replace('"%s"', '%s', $query);
$query = str_replace('%s', "'%s'", $query); // quote the strings
array_walk($args, array(&$this, 'escape_by_ref'));
return @vsprintf($query, $args); 

基本的に、wpdb-> prepare関数は "sanitize"または "clean"などの名前で呼ばれるべきです。それを "prepare"と呼ぶことは、SQLを知っている人にとっては誤解を招くでしょう。

5
user49582