ワードプレスに独自テーブルを追加するなどもをかし。
wp-db.phpをいじってはいけない!!
やり方を検索してみるとたくさんヒットするやり方が wp-includes/wp-db.php を直接編集するというもの。
wp-includesやwp-admin内のコアファイルを直接編集するということは、絶対にやってはなりません!!!『絶対にダメ』です。
ワードプレスで利用するテーブルのリスト
通常、ワードプレスをインストールする際にはユーザーがデータベースを準備して、その情報を wp-config.php に記述します。でも、テーブルをユーザーが作ることはないですね。ワードプレスのインストール時に必要なテーブルは自動的に生成されます。
この作業は /wp-admin/includes/schema.php に記述されています。
あと、意識することも無いのですが、プラグインを追加した時にプラグイン独自のテーブルが生成されているなんてこともあります。
上で直接編集するな!!と言った wp-includes/wp-db.php では、 wpdb というクラスが定義されています。 $wpdb というオブジェクトをグローバルで利用できるようにするための仕組みで、これによってデータベースとのデータのやり取りはほぼ全てカバーされています。
このファイルの255行目〜466行目あたり(Wordpress 5.7.2の場合)に、データベース内で、ワードプレスがどのテーブルを使うか、というリストがあり、 $tables という配列におさまっています。
/**
* List of WordPress per-blog tables.
*
* @since 2.5.0
* @see wpdb::tables()
* @var array
*/
public $tables = array(
'posts',
'comments',
'links',
'options',
'postmeta',
'terms',
'term_taxonomy',
'term_relationships',
'termmeta',
'commentmeta',
);
〜後略〜
これがどういうことかというと、 $tables 配列に記述されていないテーブルは、基本的にはデータベース上に存在していてもワードプレスは読み込んでくれない、つまり、独自にデータベースにテーブルを追加した「だけ」では、ワードプレス上では使えないのです。
なので、この $tables に追加するテーブル名を追記してやる必要があるということで、この wp-db.php に直接記述するということをやる馬鹿が出現するわけです。
wp-db.phpを直接編集せずに実現するには?
とりあえず wp-db.php の冒頭部分(46行目あたり)を読め。
* It is possible to replace this class with your own by setting the $wpdb global variable
* in wp-content/db.php file to your class. The wpdb class will still be included, so you can
* extend it or simply use your own.
ちゃんと教えてくれてる。
wp-content ディレクトリ直下に db.php というファイルを作ったらそれを読み込んであげるよ、と。いわゆる「ドロップイン」というやつです。変更部分だけをextendしたらいいと。ちゃんと教えてくれてるじゃん。
※ ドロップインについてはこちらが分かりやすいです。
ドロップインでWordPress本体をカスタマイズする。機能拡張のためのテンプレート
実践
さて、では例えば、独自テーブルとして「history」といったものを追加したい場合を考えます。
wp-config.php で指定したデータベースのプレフィックスが
/**
* WordPress Database Table prefix.
*
* You can have multiple installations in one database if you give each
* a unique prefix. Only numbers, letters, and underscores please!
*/
$table_prefix = 'wp_';
ならば、使用中のデータベースに追加すべきテーブル名は
wp_history
となります。
phpMyAdminを使うなり何かのツールを使うなりして、テーブル wp_history を加えましょう。
次に、 wp-content 直下に db.php というファイルを作り、以下のように記述します。
<?php
require_once(ABSPATH.WPINC.'/wp-db.php');
class my_wpdb extends wpdb {
public $tables = array(
'posts',
'comments',
'links',
'options',
'postmeta',
'terms',
'term_taxonomy',
'term_relationships',
'termmeta',
'commentmeta',
'history' // ←加えた!
);
}
if( !isset($wpdb) ) {
$wpdb = new my_wpdb( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST );
}
注意する点は、配列 $tables に加えるテーブル名はプレフィックスを除いたものであること。
とりあえず読み込んでいることを確認
さて、結果をテストしたいんだけれども、今インストールしたてでまだ湯気が出てるぐらいのワードプレスなので、どうしたものか。
とりあえずデフォでテーマはtwentytwentyoneになっているようなので、テーマフォルダの page.php を複製して page-sample.php とでもしておき、冒頭に
<?php
/*
* Template Name: テストページのテンプレ
*/
?>
これだけ加え、固定ページ→サンプルページにこのテンプレファイルを適用する。
とりあえずこれで任意のPHPコードを表示する準備はできた、と。
wpdbクラスの使い方については公式のcode referenceを参照(英語)。
Code Reference - wpdb
ちなみに、追加したwp_historyテーブルにはこんなデータを格納しました。
ID | year | event |
---|---|---|
1 | 794 | 鶯が鳴いたり平安京ができたり。 |
2 | 710 | 平城京はなんとも綺麗。 |
では、page-sample.phpのループ外
while ( have_posts() ) : 〜 endwhile; // End of the loop.
// これの外側
のどこでもいいからちょっと落書き。
とりあえずちゃんとテーブルからデータを取ってきてることだけ確認できたらいい。
<?php
global $wpdb;
$results = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}history");
print_r($results);
?>
出力結果(htmlソースの方で見てます)は
Array
(
[0] => stdClass Object
(
[id] => 1
[year] => 794
[event] => 鶯が鳴いたり平安京ができたり。
)
[1] => stdClass Object
(
[id] => 2
[year] => 710
[event] => 平城京はなんとも綺麗。
)
)
ちゃんと取得できてる。
めでたしめでたし。
ちょいと不可解な展開が・・・
変更を巻き戻してみると・・・?
とりあえずちゃんとテーブルを認識してデータ取得ができたところで、上で追加した wp-content/db.php を読み込まなかったら(データベース上のテーブルはそのまま)、テーブルを読んでくれないことを確認してみよう。
あくまでも確認です。
ん?なんじゃ?
読み込めてるwww あれ?読み込めないんじゃなかったんかいな。
最初から$tablesに追加しないテーブルを用意する。
ということでちょっと実験してみましょう。
プレフィックス有り/無しでテーブルを一つずつ追加して、db.phpは用意せず、テーブルを読み込むかどうか実験する。
テーブルは
-
プレフィックスあり wp_geograpy
-
プレフィックスなし geograpy
以下のものを追加する。
テーブル:wp_geograpy
id | country |
---|---|
1 | japan |
2 | china |
テーブル:geography
id | country |
---|---|
1 | USA |
2 | canada |
で、出るべき結果は、「これら二つのテーブルはどちらもWPで読み込まれませんでした」というものですが、この流れだと、「プレフィックス有りの方は読み込みましたが、プレフィックス無しの方は読み込みませんでした」という結果ならギリ納得せざるを得ないかも。
そんな感じでいざスタート!
出力テスト
<?php
global $wpdb;
// プレフィックス付き
$result1 = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}geograpy");
print_r($result1);
// プレフィックス無し
$result2 = $wpdb->get_results( "SELECT * FROM geograpy");
print_r($result2);
?>
出力結果
Array
(
[0] => stdClass Object
(
[id] => 1
[country] => japan
)
[1] => stdClass Object
(
[id] => 2
[country] => china
)
)
Array
(
[0] => stdClass Object
(
[id] => 1
[country] => USA
)
[1] => stdClass Object
(
[id] => 2
[country] => canada
)
)
あちゃ〜〜・・・両方出力できてるやん・・・
データ書き込みをテストしてみる
プレフィックスの有無に拘わらず、$tablesへの記述も無しにデータを読み出せてしまいました。
じゃあ書き込みもできるのでしょうか。まあできるんだろうなぁ・・・。
ということでやってみます。
wpdbクラスを利用してテーブルにデータを書き込むメソッドは以下の通り。
$wpdb->insert( $table, $data, $format );
二つのgeograpyテーブルにデータを書き込んでみます。
公式のサンプルコードを見ると、この$tableにはプレフィックスを含まないように見えるんだけど、どうなんだろう?そうだとすると、プレフィックス無しのテーブルはここで脱落するのではなかろうか?プレフィックス有り/無し両方でやってみます。
<?php
global $wpdb;
// プレフィックス有り
$wpdb->insert(
'wp_geograpy',
array(
'id' => '',
'country' => 'korea',
),
array(
'%d',
'%s',
)
);
$result1 = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}geograpy");
print_r($result1);
// プレフィックス無し
$wpdb->insert(
'geograpy',
array(
'id' => '',
'country' => 'mexico',
),
array(
'%d',
'%s',
)
);
$result2 = $wpdb->get_results( "SELECT * FROM geograpy");
print_r($result2);
?>
出力結果
Array
(
[0] => stdClass Object
(
[id] => 1
[country] => japan
)
[1] => stdClass Object
(
[id] => 2
[country] => china
)
[2] => stdClass Object
(
[id] => 3
[country] => korea
)
)
Array
(
[0] => stdClass Object
(
[id] => 1
[country] => USA
)
[1] => stdClass Object
(
[id] => 2
[country] => canada
)
[2] => stdClass Object
(
[id] => 3
[country] => mexico
)
)
よっしゃ完璧!!!
・・・ってなんでやねん!
書き込みも出来てるし。db.phpでwpdbクラスに追記してやらなくても、読み書きともに出来てるし。
上の方で、
$tables 配列に記述されていないテーブルは、使用中のデータベースに存在していてもワードプレスは読み込んでくれない、つまり、独自にデータベースにテーブルを追加した「だけ」では、ワードプレス上では使えないのです。
と書いたところなんですけど、どうしてくれますの??
う〜〜〜ん、これは調べてみないとね。
結論:普通に独自テーブルを追加するだけで使える。
とりあえず、db.phpへの記述は念の為にしておいた方が安心ではあるので、やっておきましょう。
けど、無くてもできるで!!みたいな。
う〜〜ん、分からん。
まあ、とりあえずwpdbクラスの各種メソッドを使いこなせるように勉強しましょう、というぐらいですな。
以上!!
ディスカッション
ピンバック & トラックバック一覧
[…] 参考URL:ワードプレスに独自テーブルを追加するなどもをかし。 […]