ワードプレスにおいて、DBデータの取得・登録といった基本操作方法をまとめます。
wpdbクラスはワードプレスで用意されているクラスであり、ここにDB操作に必要な関数が定義されています。
codexをみても関数の種類が多く、"自分がどの関数を使えばよいかパッと見で判断できない"ということが多いため、早見表を作りました。
wpdbクラスの概要
詳細な内容は、codexのwpdbに関するページにて確認できます。
インスタンスの扱い方
接続したいDBによって、インスタンスの扱い方は以下となります。
ワードプレスで利用しているデータベースと接続したい場合
グローバル変数「$wpdb」にて、インスタンスを管理しています。
これは、ワードプレス側で管理しているため、開発者はインスタンス生成する必要がなく、単純に$wpdbにて関数呼び出しを行うことでDB操作が可能です。
以下、サンプルです。
get_results( 'SELECT * FROM wp_options WHERE option_id = 1', OBJECT );
?>
上記のように、グローバル変数$wpdbを利用するためには、各テンプレートファイルにて『global $wpdb;』を宣言することで利用可能となります。
ワードプレスで利用していないデータベースと接続したい場合
必要なデータベース接続情報を設定の上で、インスタンスを新しく生成する必要があります。
基本的に、他システムのDBを直接参照するようなマネはしない方がよろしいので、今回はサンプルコードを割愛します。(というか調べてません。)
SQLのエスケープ[prepare()]
SQLインジェクション対策のために、wpdbクラスではprepare()メソッドが用意されています。
escape()メソッドやescape_by_ref()メソッドも用意されていますが、ver5.0.3時点では非推奨です。
特別な理由がなければprepare()メソッドを用いましょう。
引数
- 第1引数:実行対象のSQL文
- 第2引数以降:SQLのプレースフォルダに代入する値。オプション指定のため存在しない場合は未指定でOK。
戻り値
エスケープされたSQL文。
サンプル
以下のサンプルでは、foo=の部分に$name変数の値を、status=の部分に$status変数の値をそれぞれ代入した上で、SQL文を無害化しています。
prepare(
"SELECT something FROM table WHERE foo = %s and status = %d",
$name, // 未エスケープの文字列 (関数が無害化します)
$status // 信頼できない整数値 (関数が無害化します)
);
?>
より詳しく知りたい場合は、codexのデータ検証に関するページを参照してください。
任意のSQLを実行する関数[query()]
任意のSQLを実行するためには、query()メソッドを利用します。
引数として、prepare()メソッドの返り値を渡してあげます。
引数
- 第1引数:実行対象のSQL文
戻り値
- SQLの実行に成功した場合:True
- SQLの実行に失敗した場合:False
サンプル
query( $wpdb->prepare(
"
INSERT INTO $wpdb->postmeta
( post_id, meta_key, meta_value )
VALUES ( %d, %s, %s )
",
10,
$metakey,
$metavalue
) );
?>
wpdbクラスを用いたデータ操作
複数行×複数列のデータ抽出(select)[get_result()]
一般的なselect文を発行して結果を得たい場合はget_results()メソッドを利用します。
引数
- 第1引数:実行対象のselect文
- 第2引数:戻り値の型としてOBJECT、OBJECT_K、ARRAY_A、ARRAY_Nのどれかを指定
戻り値
第2引数で指定した型のデータが返却されます。詳細はサンプル部分をご確認ください。
- OBJECT:行レコードをオブジェクト化したもののインデックス配列
- OBJECT_K:行レコードをオブジェクト化したものの連想配列(キーは第1カラムの値)
- ARRAY_A:行レコードを連想配列化したもののインデックス配列
- ARRAY_N:行レコードをインデックス配列化したもののインデックス配列
サンプル
第2引数で「OBJECT」を指定した場合。
get_results(
"
SELECT ID, post_title
FROM $wpdb->posts
WHERE post_status = 'draft'
AND post_author = 5
"
); // 第2引数を指定しない場合はデフォルトの"OBJECT"となる
// オブジェクトがインデックス配列で返却されるため、カラム値を取得しようとすると以下のような記述となる。
foreach($rows as $row) {
$id = $row->ID;
}
?>
第2引数で「OBJECT_K」を指定した場合。
get_results(
"
SELECT ID, post_title
FROM $wpdb->posts
WHERE post_status = 'draft'
AND post_author = 5
","OBJECT_K"
);
// オブジェクトの連想配列で返却されるため、カラム値を取得しようとすると以下のような記述となる。
foreach($rows as $row) {
$id = $row->ID;
}
// 例えば、IDが第1カラムで、かつID=2のレコード情報を取得したい場合は以下の通り。
$title = $rows[2]->TITLE;
?>
第2引数で「ARRAY_A」を指定した場合。
get_results(
"
SELECT ID, post_title
FROM $wpdb->posts
WHERE post_status = 'draft'
AND post_author = 5
","ARRAY_A"
);
//連想配列のインデックス配列で返却されるため、カラム値を取得しようとすると以下のような記述となる。
foreach($rows as $row) {
$id = $row['ID'];
}
?>
第2引数で「ARRAY_N」を指定した場合。
get_results(
"
SELECT ID, post_title
FROM $wpdb->posts
WHERE post_status = 'draft'
AND post_author = 5
","ARRAY_N"
);
// インデックス配列のインデックス配列で返却されるため、カラム値を取得しようとすると以下のような記述となる。
// 例えば、IDが1カラム目の場合は以下の通り。
foreach($rows as $row) {
$id = $row[0]; // 0は1カラム目を表す。2カラム目の場合は1を指定する。
}
?>
単一列のデータ抽出(select)[get_col()]
引数
- 第1引数:実行対象のselect文
- 第2引数:取得対象の列番号(1列目を指定する時は0を指定)
第2引数は、複数列取得される場合に、何列目を取得対象とするか?を指定できます。
戻り値
取得した列の配列
サンプル
<?php $col_list = $wpdb->get_col( "SELECT * FROM $wpdb->users", 4 ); foreach ( $col_list as $elem ) { echo $elem; } ?>
単一行のデータ抽出(select)[get_row()]
引数
- 第1引数:実行対象のselect文
- 第2引数:戻り値の型としてOBJECT、ARRAY_A、ARRAY_Nのどれかを指定
- 第3引数:取得対象の行番号
戻り値
取得した行情報。第2引数で指定した型のデータで返却される。
- OBJECT:行レコードをオブジェクト化したもののインデックス配列
- ARRAY_A:行レコードを連想配列化したもののインデックス配列
- ARRAY_N:行レコードをインデックス配列化したもののインデックス配列
各型の扱い型については、get_result()のサンプル部分にまとめていますので、そちらをご参照ください。
サンプル
<?php $result_list = $wpdb->get_row( "SELECT * FROM $wpdb->users", ARRAY_A, 0 ); echo $result_list['user_name']; ?>
単一の値データ抽出(select)[get_var()]
引数
- 第1引数:実行対象のselect文
- 第2引数:取得対象の列番号(1列目を指定する時は0を指定)
- 第3引数:取得対象の行番号(1行目を指定する時は0を指定)
第2引数と第3引数は、select句で複数列×複数行の取得を指定した際に、何列目の何行目の値をget_var()での取得値とするかを指定することができます。
戻り値
取得できた単一の値。
サンプル
<?php $user_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->users" ); echo "<p>User count is {$user_count}</p>"; ?>
データ登録(insert)[insert()]
insert文の実行を行いたい場合はinsert()メソッドを利用します。
引数
- 第1引数:対象テーブル
- 第2引数:挿入データ(キー:カラム名、値:設定値の連想配列で設定)
- 第3引数:データフォーマット(第2引数と対応させる形で配列で指定)(%s:文字列、%d:整数、%f:浮動小数点数のいずれかを指定)
戻り値
- 行を挿入できた場合:1(insertできた行数=常に1)
- 行の挿入に失敗した場合:false
サンプル
insert(
'table',
array(
'column1' => 'value1',
'column2' => 123
),
array(
'%s',
'%d'
)
);
?>
データ変更(update)[update()]
登録済みデータの変更については、update()とreplace()の2パターンありますが、replace()は使いにくそうなので、update()を使うこととします。
引き数
- 第1引数:対象テーブル
- 第2引数:更新するデータ(キー:カラム名、値:設定値の連想配列で設定)
- 第3引数:where句として使う名前付き配列(キー:カラム名、値:設定値の連想配列で設定)
- 第4引数:データフォーマット(第2引数と対応させる形で配列で指定)(%s:文字列、%d:整数、%f:浮動小数点数のいずれかを指定)
- 第5引数:データフォーマット(第3引数と対応させる形で配列で指定)(%s:文字列、%d:整数、%f:浮動小数点数のいずれかを指定)
戻り値
- 更新に成功した場合:1(更新されたレコード数=1)
- 指定データと既存データが同一だった場合:0(更新されない=更新されたレコード数が0)
- 更新に失敗した場合:false
サンプル
update(
'table',
array(
'column1' => 'value1', // string
'column2' => 'value2' // integer (number)
),
array( 'ID' => 1 ),
array(
'%s', // value1
'%d' // value2
),
array( '%d' )
);
?>
データ削除(delete)[delete()]
delete文発行したい場合はdelete()メソッドを利用します。
引数
- 第1引数:テーブル名
- 第2引数:where句として使う名前付き配列(キー:カラム名、値:設定値の連想配列で設定)
- 第3引数:データフォーマット(第2引数と対応させる形で配列で指定)(%s:文字列、%d:整数、%f:浮動小数点数のいずれかを指定)
戻り値
- 行削除できた場合:1(削除された行数=1)
- 削除対象行が存在しなかった場合:0(削除された行数=0)
- エラーが発生した場合:false
サンプル
delete( 'table', array( 'ID' => 1 ), array( '%d' ) );
?>
wpdbクラスを用いたデータ定義
プラグインを作成する際は、専用のテーブルを定義することがあります。
その際は、以下の2種類の関数を用いて実現できます。
また、テーブル定義用の関数を実装したら、プラグインのメインファイルにて以下のように呼び出しを行い、プラグインインストール時に適用されるようにします。
任意のDDLを実行[query()]
query()メソッドを利用します。
こちらのメソッドの利用方法については、すでに説明済みのためここでは省略します。
テーブルの作成・変更[dbDelta()]
テーブルの作成・変更をしたい場合はdbDelta()関数を利用することもできます。
この関数の引数としてcreate文を渡してやると、テーブルが存在しない場合は作成し、テーブルがすでに存在する場合は差分をalter tableで反映してくれます。
ただし、利用するに当たって以下の制約があるため、標準SQLの利用に慣れている人はquery()メソッドで一本化してもよさそうに思います。
dbDelta()関数利用時の制約
実行するcreate文を作成する際に、以下の制約があります。
- 1 行につき、ひとつのフィールドを定義してください。〔訳注:ひとつの行に複数のフィールド定義を書くことはできません。さもなくば ALTER TABLE が正しく実行されず、プラグインのバージョンアップに失敗します。〕
- PRIMARY KEY というキーワードと、主キーの定義の間には、二つのスペースが必要です。
- INDEX という同義語ではなく、KEY というキーワードを使う必要があります。さらに最低ひとつの KEY を含めなければなりません。
- フィールド名のまわりにアポストロフィ(')やバッククォート(`)を使ってはいけません。
- フィールドタイプはすべて小文字であること。
- SQL キーワード、例えば CREATE TABLE や UPDATE は、大文字であること。
- 長さパラメータを受け付けるすべてのフィールドに長さを指定すること。例えば int(11) のように。
- この関数を利用するためには、wp-admin/includes/upgrade.phpをインクルードする必要があります。
引数
- 第1引数:SQL
戻り値
なし。
サンプル
以下、dbDelta()関数を利用するサンプルです。
サンプル中に記述はされていませんが、設定中のテーブル名接頭辞を取得してから、登録テーブル名にも利用するといった手順を踏む方が安全です。
get_charset_collate();
$sql = "CREATE TABLE $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
name tinytext NOT NULL,
text text NOT NULL,
url varchar(55) DEFAULT '' NOT NULL,
UNIQUE KEY id (id)
) $charset_collate;";
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );
?>