こんにちは。でんすけ(@notgeek_densuke)です。
WordPressを使って色々記事を書いていると、
どうしてもデータベースを使ってデータを整理したい!
という場合があるかと思います。
あるはず。あるよね!
そんなわけで、WordPressからDBを扱う方法、というのをまとめてみたいと思います。
スポンサーリンク
WordPressでDBを使いたいとき、とは?
そもそも、なんのためにDBを使いたいと思うのか、というと。
・データがたくさんある
・後々そのデータが増えるかもしれない
というような条件で記事を書くときです。
例えば。
手前味噌ですが、僕が運営している姉妹ブログで、スプラトゥーン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