WordPress にはデータベース操作用のクラス関数が用意されている。このクラスは wpdb と呼ばれておりこれを使ってWordPressで使っているデータベースにアクセスすることができる。
使い方
wpdbクラスのメソッドは、直接呼び出すのではなく、WordPress にはデータベースと対話するために設定されたクラスをインスタンス化した $wpdbというグローバル変数がある。このグローバル変数 $wpdbを使うには、グローバル宣言が必要である。
データベースへ任意のクエリを送信
query 関数を使えば、WordPress データベースであらゆる SQL クエリを実行できる。
<?php $wpdb->(‘query’); ?>
query (文字列) :実行したい SQL文。
この関数は影響する行または選択された行の数を整数で返す。もし MySQL エラーが発生した場合は、FALSEを返す (注: 0 または FALSE が返される可能性があるため、正しい比較演算子を使うこと。例えば、等価演算子 == や 厳密な等価演算子 ===)
例
ID が13の投稿から ‘gargle’ メタキーおよび値を削除する。
$wpdb->query(" DELETE FROM $wpdb->postmeta WHERE post_id = '13' AND meta_key = 'gargle'");
ID が15の固定ページの親ページを、ID が7のページに指定する。
$wpdb->query(" UPDATE $wpdb->posts SET post_parent = 7 WHERE ID = 15 AND post_status = 'static'");
変数の SELECT
get_var関数はデータベースから変数を一つ返す。変数は一つしか返らないが、クエリの結果はすべてキャッシュされ、あとから使うことができる。マッチするものがない場合、NULL が返される。
<?php $wpdb->get_var('query',column_offset,row_offset); ?>
- query
- (文字列) 実行したい SQL クエリ。パラメータを
null
にすると、前回のクエリ結果のキャッシュ中から指定した変数を返す。 - column_offset
- (整数) 必要としている列のオフセット (一つ目は 0)。初期値は 0。
- row_offset
- (整数) 必要としている行のオフセット (一つ目は 0)。初期値は 0。
例
ユーザーの数を取得し表示する。
<?php $user_count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $wpdb->users;")); echo '<p>現ユーザー数は、' . $user_count . '人です。</p>'; ?>
カスタムフィールドの数値合計を返し、表示する。
<?php $meta_key = 'kilometers'; //実在するメタキーに変更する $kms=$wpdb->get_var($wpdb->prepare("SELECT sum(meta_value) FROM $wpdb->postmeta WHERE meta_key = %s", $meta_key)); echo '<p>合計距離は'. $kms . 'kmです。</p>'; ?>
行の SELECT
クエリから行全体を取り出すには、get_row
を使う。この関数を使うと行がオブジェクト、連想配列、またはインデックス配列として返される。クエリが一つ以上の行にマッチする場合は、あとから使えるようにすべての行がキャッシュされるが、実際に返されるのは指定された行のみである。
<?php $wpdb->get_row('query', output_type, row_offset); ?>
- query
- (文字列) 実行したいクエリ。
- output_type
- 以下の定数のいずれか。初期値は OBJECT。
- OBJECT – 結果をオブジェクトとして出力。
- ARRAY_A – 結果を連想配列として出力。
- ARRAY_N – 結果をインデックス配列として出力。
- row_offset
- (整数) 必要としている行のオフセット (一つ目は 0)。初期値は 0。
例
リンク ID 10に関する情報をすべて取得する。
$mylink = $wpdb->get_row("SELECT * FROM $wpdb->links WHERE link_id = 10");
連想配列にする場合。
$mylink = $wpdb->get_row("SELECT * FROM $wpdb->links WHERE link_id = 10", ARRAY_A);
列の SELECT
列を SELECT するには、get_col
を使う。この関数は. 多次元配列を出力する。クエリによって複数の列が返された場合、列は一つしか返ってこないが、クエリの結果はすべてキャッシュされ、あとから使うことができる。
<?php $wpdb->get_col('query',column_offset); ?>
query
(文字列) 実行したい SQL クエリ。パラメータを null
にすると、前回のクエリ結果のキャッシュ中から指定した行を返す。
column_offset
(整数) 必要としている列のオフセット (一つ目は 0)。初期値は 0。
例
車に関するブログにて、車 (例: 1969年製のフォードマスタング) についてモデル・製造年・メーカーという3つのカスタムフィールドが設定されている。以下の例では、メーカー名 (フォード) によってフィルターされた投稿のタイトルを、モデルと製造年でソートして出力する場合のコードを紹介している。
<?php $meta_key1 = 'モデル'; $meta_key2 = '製造年'; $meta_key3 = 'メーカー'; $meta_key3_value = 'フォード'; $postids=$wpdb->get_col($wpdb->prepare(" SELECT key3.post_id FROM $wpdb->postmeta key3 INNER JOIN $wpdb->postmeta key1 on key1.post_id = key3.post_id and key1.meta_key = %s INNER JOIN $wpdb->postmeta key2 on key2.post_id = key3.post_id and key2.meta_key = %s WHERE key3.meta_key = %s and key3.meta_value = %s ORDER BY key1.meta_value, key2.meta_value",$meta_key1, $meta_key2, $meta_key3, $meta_key3_value)); if ($postids) { echo $meta_key3_value . '一覧 (' . $meta_key1 . '・' . $meta_key2 .'順)'; foreach ($postids as $id) { $post=get_post(intval($id)); setup_postdata($post);?> <p><a href="<?php the_permalink() ?>" rel="bookmark" title="<?php the_title_attribute(); ?>へのパーマリンク"><?php the_title(); ?></a></p> <?php } } ?>
一般的な結果の SELECT
get_results
を使うと、データベースから一般的な複数行の結果を取ってくることができる。この関数はクエリの結果全体を配列として返す。この配列の各要素はクエリ結果の各行と対応しており、get_row
と同じくオブジェクト、連想配列、またはインデックス配列のいずれかを指定することができる。
<?php $wpdb->get_results('query', output_type); ?>
- query
- (文字列) 実行したい SQL クエリ。パラメータを
null
にすると、前回のクエリ結果のキャッシュ中からデータを返す。
output_type
以下の定数のいずれか。初期値は OBJECT。詳細および例については、行の SELECTセクションを参照。
- OBJECT – 結果をオブジェクトとして出力。
- ARRAY_A – 結果を連想配列として出力。
- ARRAY_N – 結果をインデックス配列として出力。
例
ID が5のユーザーのすべての下書きの ID とタイトルを取得して、タイトルを echo。
$fivesdrafts = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE post_status = 'draft' AND post_author = 5"); foreach ($fivesdrafts as $fivesdraft) { echo $fivesdraft->post_title; }
ID が5のユーザーの下書き情報をすべて取得。
<?php $fivesdrafts = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_status = 'draft' AND post_author = 5"); if ($fivesdrafts) : foreach ($fivesdrafts as $post) : setup_postdata($post); ?> <h2><a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php the_title(); ?>へのパーマリンク"><?php the_title(); ?></a></h2> <?php endforeach; else : ?> <h2>見つかりません</h2> <?php endif; ?>
行の INSERT
テーブルに行を挿入。
例
列に2つ (1つ目は文字列、2つ目は数値) 行を挿入。
$wpdb->insert( 'table', array( 'column1' => 'value1', 'column2' => 123 ), array( '%s', '%d' ) )
使用できる値: – %s (文字列) – %d (十進記数法) – %f (浮動小数点数)
列の UPDATE
テーブル内の列を更新。
例
ID が1、一つ目の列の値が文字列、2つ目の列の値が数値、という行を更新する。
$wpdb->update( 'table', array( 'column1' => 'value1', 'column2' => 'value2' ), array( 'ID' => 1 ), array( '%s', '%d' ), array( '%d' ) )
SQL インジェクション攻撃からクエリを保護する
SQL インジェクション攻撃からクエリを保護するためには、実行する前にクエリデータはすべて SQL エスケープする必要がある。これを行う際には、sprintf() に似た構文を持つprepare
メソッドを使うと便利。
<?php $sql = $wpdb->prepare( 'query'[, value_parameter, value_parameter ... ] ); ?>
- query
- (文字列) 実行したい SQL クエリ。
%s
および%d
がプレースホルダーになる。 - value_parameter
- (整数|文字列) プレースホルダーに代入する値。すでに SQL エスケープされている値は使えない。
例
ID 10の投稿に、”孔子の教え” => “故きを温めて新しきを知る、以て師と為るべし。” というメタキー => 値のペアを追加する。
$metakey = "孔子の教え"; $metavalue = "故きを温めて新しきを知る、以て師と為るべし。"; $wpdb->query( $wpdb->prepare( " INSERT INTO $wpdb->postmeta ( post_id, meta_key, meta_value ) VALUES ( %d, %s, %s )", 10, $metakey, $metavalue ) );
文字列をクオートで囲む必要がない点に注目。SQL クエリに変数を直接渡すのではなく、文字列には %s
プレースホルダーを、整数には %d
プレースホルダーを使っている。渡す値の数に制限はなく。それぞれ、prepare()
メソッドで新しいパラメーターにする。