データベースのアクセス

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() メソッドで新しいパラメーターにする。