WordPressに少し慣れてくるといよいよ自分でプラグインを作ったりしたいなと思ってくると思います。またプラグインじゃなくても、せっかくWordpressサーバを持っているんだから、これを活用して、Wordpress上にインタラクティブなアプリとか作ったら面白いんじゃないかとか思ったしませんか?
そんなわけで今回は「Wordpressでデータベースにアクセスする方法」をまとめておきます。
WordPressでのデータベースの考え方
WordPressも要はSQLサーバ上に動いているだけなので、通常通りSQLに接続してあげても良いんですが、Wordpressの場合はデータベースに接続するための便利なオブジェクト$wpdbが既に準備されているんです。
なので、Wordpress Database内のテーブルにアクセスするのであれば、この$wpdbを使えば、記述がとても短く安全に接続できます。また面倒なSQLインジェクションの対策などもこの$wpdbを正しく使えばオブジェクト内で対応してくれているらしいので、それもまた便利ですね。
WordPress Databaseの中身
先ずはWordpressサーバ内にどんなテーブルがあるかなんですが、SQLターミナルに入ってあげてTableを表示してあげるとこんな感じです。因みにこのWordpressはCocoonテーマを使用した場合のテーブル例になるので、既にcocoonでいくつかテーブルができていることがわかりますね。
mysql> show tables;
+---------------------------+
| Tables_in_wordpress |
+---------------------------+
| wp_cocoon_accesses |
| wp_cocoon_affiliate_tags |
| wp_cocoon_function_texts |
| wp_cocoon_item_rankings |
| wp_cocoon_speech_balloons |
| wp_commentmeta |
| wp_comments |
| wp_links |
| wp_options |
| wp_postmeta |
| wp_posts |
| wp_term_relationships |
| wp_term_taxonomy |
| wp_termmeta |
| wp_terms |
| wp_usermeta |
| wp_users |
+---------------------------+
これらの個々のテーブルの中身に関しては、また別途説明したいと思いますが、要は記事データであればwp_postsにデータが入っていたり、コメントであればwp_commentsのテーブルに格納されるというわけです。
これらのデータを上手く活用することで、自分なりのプラグインを作成したりできますし、もしくは新しくテーブルを作成することで、新しいデータテーブルを作ることもできるわけですね。
$wpdbを使用する方法
さて、次にこれらのテーブルにWordpress上のファイル(PHPなど)からアクセスする方法ですが、手順として以下のような感じです。
- wp-load.phpをrequireもしくはincludeでロードする
- global $wpdbを宣言する
- SQL文を作成して$wpdbメソッドでクエリを実行
- 結果を配列に入れる
手順にするとなかなか長くなるんですが、コードとしてはそんなに長くはないです。一つずつ説明していきますね。
wp_load.phpをrequireもしくはincludeでロードする
$wpdbにアクセスするためというよりも、wordpressのデータベースにアクセスするためのアクセス情報がありますよね?SQLサーバのURLだったり、ユーザ/パスワードであったりと。
こういった情報をプラグインのPHPなどのコードに直接書き込むのは正直セキュリティ的にも良くないですし、何よりも冗長になります。
WordPressではこういったDB情報は全てwp-config.phpに纏められているので、これを使いましょう。wp-config.phpの中身ではこんな感じでDB情報を纏められています。
/** WordPress のためのデータベース名 */
define( 'DB_NAME', 'wordpress' );
/** MySQL データベースのユーザー名 */
define( 'DB_USER', 'lilygff43khf' );
/** MySQL データベースのパスワード */
define( 'DB_PASSWORD', '35o7auirffrfa****' );
/** MySQL のホスト名 */
define( 'DB_HOST', 'localhost' );
なので、自分で作成する場合はPHPのコードにwp-config.phpをロードしてあげれば良いんですが、直接ロードするのはwordpressの順番的に良くないらしいので、wp-load.phpをロードしましょう。
書き方はこんな感じになります。PHPコードの冒頭にこんな感じで書きましょう。
require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/wp-load.php';
dirname()の部分はそのPHPファイルがサーバ上のどこにあるか依存しますが、上記の例はプラグインフォルダ直下のケースです。./wp-load.php/wp-contens/plugins/PLUGINNAME/sample.phpのようなケースですね。
そのため4階層上のディレクトリにwp-load.phpがあるからそれをinclude_onceで読み込みます。
因みにロードするための関数は今回のものを含めて4つあります。
- include
- include_once
- require
- require_once
それぞれ動き方が違ってきて、必要に応じて使い分けるようにしましょう。区分としてこんな感じになります。
ロード関数 | 動作 | 用途 |
---|---|---|
include() | 外部ファイルを読み込んで、失敗してもWarningを出して動作を続ける | 読み込めなくても動作する場合 |
include_once() | include関数の動作、既に読み込んでいる場合は実行しない | 同上 |
require() | 外部ファイルを読み込んで、失敗するとFatal Errorを出して動作が止まる | 読込不可の場合、動作処理しない場合(コア処理など) |
require_once() | require関数の動作、既に読み込んでいる場合は実行しない | 同上 |
global $wpdbを宣言する
WordPressのデータベースは、$wpdbというオブジェクトが既に用意されているので、使うことを宣言するだけでOKです。
宣言する場合に必ずglobalで宣言するようにしてください。
global $wpdb;
SQL文を作成する
次にSQLクエリの作成です。
SQLクエリを作成・実行する処理はいくつかあるのですが、基本的にはSQLインジェクションなどの対策を実施するために、クエリ文を直接書くような真似はやめましょう。
SQLを使う場合にはPOSTなどで検索値を取得してきていると思いますが、こういった内容を直接SQL文としてクエリにするのは、SQLインジェクションを招きかねないので、必ずSELECTの場合であれば、$wpdb->prepareを使うようにしましょう。
$value1_id =$_POST['value1'];
$value2_id =$_POST['value2'];
$db_table = 'wp_sample_table';
//SQL文
$query = "SELECT * FROM " . $db_table . " WHERE value1_id = %s AND value2_id = %s;
//SQLクエリを連想配列で取得
$results = $wpdb->get_results($wpdb->prepare($query,$value1_id,$value2_id),"ARRAY_A");
$db_tableはテーブル名を格納する部分ですが、この部分は固定で繋げていますが、本来は$wpdb->sample_tableという書き方にして、”SELECT * FROM $wpdb->sample_table WHERE”でも良いはずなんですが、ワタシの環境では上手くいかなかったので、今は良しとしましょう。
こういう書き方($wpdb->xxxxx)でも良いということだけ覚えておきましょう。
SQLクエリの実行は、$wpdb->get_resultsで$wpdb->prepareを実行するという処理にしています。今回は複数行の実行結果をもらいたいので、get_resultsメソッドを使用していますが、単一結果が欲しい場合には、get_varなどを使ってください。
wpdbのSELECT操作 | 実行結果 |
---|---|
$wpdb->get_results() | 複数行 |
$wpdb->get_var() | 単一行 |
$wpdb->query() | クエリ自体を単純に実行する |
例ではget_resultsのoutput引数としてARRAY_Aを指定していますが、ここが返ってくる結果をどういう形で受取たいかになります。以下は関数レファレンスからの抜粋です。例えばARRAY_Aでは連想配列としてラベルをつけた状態でもらう事になります。
OBJECT – 結果をインデックス配列として出力。要素は行オブジェクト。
OBJECT_K – 結果を連想配列として出力。第1カラムの値をキー(重複は無視される)、行オブジェクトを値とする。
ARRAY_A – 結果をインデックス配列として出力。要素は1行を表す連想配列で、そのキーはカラム名。
ARRAY_N – 結果をインデックス配列として出力。要素は1行を表すインデックス配列。
https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/wpdb_Class
次に$wpdb->prepareの操作ですが、これはプレースホルダという書き方で書いており、予めクエリ文に変数を入れる部分(%dもしくは%s)を型指定で入れておくことで、変数をSQL実行の後からバインドすることができます。
これがSQLインジェクション対策となる書き方となりますので、wpdbのdb操作の場合はこの書き方にしましょう。因みに%dは整数型指定で、%sは文字列指定になります。
詳細の構文はwpdbのリファレンスを確認してください。
https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/wpdb_Class
結果を配列に入れる
あとはDBの結果を配列に入れるだけですね。今回は連想配列で取得しているので、ラベルを使って値を取っていますが、そうでない場合は単純にrow[0]やrow[1]で順番に取ります。
個人的には連想配列で取ってくるのが一番直感的にわかりやすいですね。
$count = 0;
foreach ($results as $row){
$arry_val[$count] = array(
'value1_id' => $row['value1_id'],
'value2_id' => $row['value2_id']
);
count++;
}
まとめ
今回は自分の備忘録がわりにもなりますが、wordpressでのDB操作方法の書き方について纏めました。要はステップとして以下の4つだけを必ず記載すればあとはどうにでもなりますね。
- wp-load.phpをrequireもしくはincludeでロードする
- global $wpdbを宣言する
- SQL文を作成して$wpdbメソッドでクエリを実行
- 結果を配列に入れる
最後に紹介した全てのコードをまとめて書くとこんな感じになりますね。ではEnjoy WordPress!
require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/wp-load.php';
global $wpdb;
$value1_id =$_POST['value1'];
$value2_id =$_POST['value2'];
$db_table = 'wp_sample_table';
//SQL文
$query = "SELECT * FROM " . $db_table . " WHERE value1_id = %s AND value2_id = %s;
//SQLクエリを連想配列で取得
$results = $wpdb->get_results($wpdb->prepare($query,$value1_id,$value2_id),"ARRAY_A");
$count = 0;
foreach ($results as $row){
$arry_val[$count] = array(
'value1_id' => $row['value1_id'],
'value2_id' => $row['value2_id']
);
count++;
}
コメント