そんなにGeekじゃないエンジニアブログ

ブログ記事にデータベースを使いたい!WordPressブログでDBの独自テーブルを作ってwpdbで操作する方法

calendar

こんにちは。でんすけ(@notgeek_densuke)です。

WordPressを使って色々記事を書いていると、
どうしてもデータベースを使ってデータを整理したい!
という場合があるかと思います。

あるはず。あるよね!

そんなわけで、WordPressからDBを扱う方法、というのをまとめてみたいと思います。

スポンサーリンク

WordPressでDBを使いたいとき、とは?

そもそも、なんのためにDBを使いたいと思うのか、というと。

・データがたくさんある
・後々そのデータが増えるかもしれない

というような条件で記事を書くときです。

例えば。
手前味噌ですが、僕が運営している姉妹ブログで、スプラトゥーン2のブキ一覧を作っています。
こちら。

splatoon2(スプラトゥーン2)ブキ一覧&ナワバリバトル攻略記事一覧

このページでは、

・ブキがたくさん存在する
・各ブキに対して、同じようなフォーマットで表示する
・ブキは継続的に増えていく(新ブキが追加される)

という条件があるため、データベースで管理するのが便利だったりするわけですね。

データベースのテーブルを作る

まずは、自分が使いたいデータを入れるためのテーブルを作成します。

データベースの管理ツール「PHPMyAdmin」が使える環境であれば、
PHPMyAdminの画面からGUIでテーブルを作成することができます。

「実行」すると、各カラムのカラム名と型などを入力する画面が出てくるので、お好みで。

もしくは、「クエリ」から

CREATE TABLE IF NOT EXISTS `wp_table_name` (
  `name` varchar(255) NOT NULL,
  `num` int(11) NOT NULL
)

というようなSQLを投げてもいいです。
プライマリキーやらインデックスなんかの細かい設定はここでは省略します。

例えば、冒頭で例に挙げたスプラトゥーン2のブキ一覧では、
・ブキの名前
・サブウェポンの名前
・スペシャルウェポンの名前
などをカラムに持つテーブルを作成すればよいわけですね。

WordPressのテーブルではプレフィックスが必要

テーブル作成時に気を付けることとして
テーブル名のプレフィックスを統一する必要があります。

WordPressのインストール時に既に作成されたテーブルには「wp_~」などのプレフィックスが付いているはず。
それにならって、「wp_table_name」のようにしなければいけません。

※正確には必須ではないのですが、あとで出てくる$wpdbを使うために、統一しておくのが便利です。

このプレフィックスが何か、というのは、
WordPressインストールフォルダの直下にある「wp-config.php」を見れば確認できます。

テキストエディタでwp-config.phpを開いてみると、どこかにこういう記述があるはず。

/**
 * WordPress データベーステーブルの接頭辞
 *
 * それぞれにユニーク (一意) な接頭辞を与えることで一つのデータベースに複数の WordPress を
 * インストールすることができます。半角英数字と下線のみを使用してください。
 */
$table_prefix  = 'wp_';

なのでこのWordPressは、
テーブル名に「wp_」が付いているのが自分が使うテーブルだ!
と思っているわけです。

これに合わせて、テーブルの名前を付けてあげましょう。

データベースにデータの挿入

で、テーブルを作ったら、当然ながらデータを入れないと始まりません。

INSERT INTO `wp_table_name` (`name` ,`num`)
VALUES
    ('aaa',  '1'),
    ('bbb',  '2');

みたいな感じで、INSERTしてあげましょう。

ここまでできたらデータベース側の準備は完了です。
続いてはWordPressの設定の話。

WordPressにテーブルを認識させる

さて、テーブルを作成しましたが、
それだけでは、WordPressはテーブルの存在に気付いてくれません。

気づかせるために、少し設定を変えてあげないといけません。

よく紹介される方法が2種類あります。
両方ご紹介しますが、2つ目の方法がおススメ。

wp-db.phpで設定する

1つ目の方法は、
WordPressのインストールフォルダ―内の、
「wp-includes」の中にある「wp-db.php」を編集する方法です。

wp-db.phpをテキストエディタで開いて「$tables」などで検索すると、こんな記述が見つかるはず。

/**
 * List of WordPress per-blog tables
 *
 * @since 2.5.0
 * @see wpdb::tables()
 * @var array
 */
var $tables = array( 'posts', 'comments', 'links', 'options', 'postmeta',
	'terms', 'term_taxonomy', 'term_relationships', 'termmeta', 'commentmeta' );

このarrayの中に、自分が作成したテーブル名を追加すればいいわけです。
こんな感じ。

var $tables = array( 'posts', 'comments', 'links', 'options', 'postmeta',
	'terms', 'term_taxonomy', 'term_relationships', 'termmeta', 'commentmeta',
	'table_name');

一番最後に「table_name」を追加しました。

このときプレフィックスは付けないで追加してください。

で、これだけで設定は完了なのですが、この方法の問題点として、
WordPressのアップデートでwp-db.phpファイルが上書きされてしまう
ということがあります。

そうすると、WordPressがアップデートされるたびに追記をしなければならなくなります。
これは面倒だ。

db.phpを自作する

そこで、WordPressアップデート回避策として、
「wp-content」フォルダ内に「db.php」を自作する、という方法があります。

「wp-content」フォルダに、「db.php」作って置いちゃいます。
中身はこんな感じ。

<?php
/**
 * ファイルの説明
 *
 */

require_once( ABSPATH . WPINC . '/wp-db.php' );
class my_wpdb extends wpdb {
	// データベーステーブルの定義を変更
	var $tables = array( 'posts', 'comments', 'links', 'options', 'postmeta',
		'terms', 'term_taxonomy', 'term_relationships', 'termmeta', 'commentmeta' ,
		'table_name');
}
if ( ! isset($wpdb) ) {
    $wpdb = new my_wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
}

WordPressのPHP内で、データベースの読み書きをするのに使う変数「$wpdb」というものがあるのですが、
その「$wpdb」のクラスを継承して、「$tables」変数だけを上書きする、というやり方です。

「db.php」はWordPressのアップデートで上書きされないファイルなので、
これでいちいちアップデートを心配する必要がありません。

いちおう、こちらのやり方にも問題があって、
万が一、デフォルトで読み込まれるテーブルが増えた場合、
(=wp-db.php側で$tablesの中身が増えた場合)
db.phpの方で上書きしてしまうため、増えたテーブルを読むことができなくなります。

なので、その時はdb.php側にも、増えたテーブルを追記してやる必要が出てきます。

・・・が、そんなことはめったに起こらないと思われるので、
こちらのやり方がよさそう、というわけです。

WordPressのPHPでデータベースを読み込む「$wpdb->get_results」の使い方

さて、ここまでで下準備ができたはず。
なので、実際にデータを読み込んでみたいと思います。

例として、こんなテーブルがあって、
そこから値を取り出すことを考えてみます。

テーブル名:wp_test
name num
hoge 2
fuga 4

データベースのデータを引っ張り出してきて、単純に<table>タグに包んで表示させる、ということをやってみようと思います。
WordPressのPHP側の実装はこんな感じ。

// $wbdb利用時に書くおまじない
global $wpdb;

// テーブル内の全データをSELECT
$rows = $wpdb->get_results("SELECT * FROM $wpdb->test");

// 取得したデータ1行ごとに処理。
// データはカラム名の連想配列になっているので、
// $変数->nameのようにカラム名をそのまま指定すれば中身のデータを取得できる。
$result = "<table><tbody>";
foreach($rows as $row){
	$result .= "<tr><td>" . $row->name ."</td><td>" . $row->num ."</td></tr>";
}
$result .= "</tbody></table>";

print $result;

これで実行結果がこんな感じに。

hoge 2
fuga 4

こうしておけば、データベースにデータを追加するだけでWebサイト上に反映されて表示される(PHPやHTML上では更新が要らない)ということになるわけですね!

PHPの変数を、SQL文に反映したい場合

SQL文中に変数を入れたい時もあるかもしれません。
そんな時はこう。

global $wpdb;
$result = "<table><tbody>";
	
$pattern = "hoge";
$number = 2;

$sql = $wpdb->prepare("SELECT * FROM $wpdb->test WHERE name = %s AND num = %d", $pattern, $number);
$rows = $wpdb->get_results($sql);

foreach($rows as $row){
	$result .= "<tr><td>" . $row->name ."</td><td>" . $row->num ."</td></tr>";
}
$result .= "</tbody></table>";

return $result;

nameが「hoge」かつ、numが「2」のレコードだけ取得します。

prepare関数は、%sなどのプレースホルダーと呼ばれるものを使って、PHPの変数を利用することができます。
2つ目以降の引数に任意の値や変数を指定することで、
%sの部分を置き換えることができます。

C言語で言うprintfみたいなやつですね。

今回の例でいうと、
ひとつめの%sが$patternに、
ふたつめの%dが$numberに置き換わります。

また、このプレースホルダーを使うことで
SQLエスケープを施してくれるという利点もあります。

変数内にSQL文が格納されていたりすると、意図しないSQL文が実行される可能性があるため、それを防止してくれるわけです。

何らかの形で、
ユーザーが入力した文字を使って$wpdbを利用する、
という実装の仕方をするのであれば、このprepare関数を使用するのが望ましいと言えます。

WordPressのPHPでデータベースを更新する

さて、SELECTでデータを取得する以外にも、
INSERTやDELETE、UPDATEなどでデータベースを更新することもできます。

例えばこんな感じ。

global $wpdb;

$newname = "newhoge";
$newnum = 2;

//データをINSERTしたい場合
$sql_in = $wpdb->prepare("INSERT INTO $wpdb->test VALUES(%s , %d)" , $newname , $newnum);

//データをUPDATEしたい場合(該当データがなければINSERTされる)
$sql_up = $wpdb->prepare("UPDATE $wpdb->test SET name = %s , num = %d WHERE name = 'hoge'" , $newname , $newnum);

//データをDELETEしたい場合
$sql_del = $wpdb->prepare("DELETE FROM $wpdb->test WHERE name = %s AND num = %d" , $newname , $newnum);

$result = $wpdb->query( $sql_in );
//$result = $wpdb->query( $sql_up );
//$result = $wpdb->query( $sql_del );

if( false === $result ){
	// 失敗したときの処理~
}

ソースコードは例なのでムダに色んなクエリを書いていますが、
要するに「$wpdb->prepare」でSQL文を準備しておいて「$wpdb->query」で実行できる、ということです。

「$wpdb->prepare」の返り値は、
失敗したら「false」が、
成功したら、影響した行数が返ってくるので、
必要に応じてその後の処理を実装するとよいでしょう。

まとめ

ということで、WordPressでデータベースを使う!の巻でした。

データベースにテーブル、データを用意して、
db.phpにテーブルを記述、
あとはPHP内で$wpdbを使えば、SQL文を実行できます。

わかってしまえばそこまで難しくないはず!
データベースを使って、リッチなWebサイトを作ってみてください。

それではまたー。

この記事をシェアする

コメント

  • ありがとうございます!!
    おかげさまで運営しているゲームブログの中に
    データベースを作成できました。
    こちらのページを発見できなかったら無理だったなと思います。

    by 花梨 2019年5月21日 9:28 PM

down コメントを残す




CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください