当サイト、Codex 日本語版は今後積極的な更新は行わない予定です。後継となる新ユーザーマニュアルは、https://ja.wordpress.org/support/ にあります。
万が一、当サイトで重大な問題を発見した際などは、フォーラムWordSlack #docs チャンネルでお知らせください。</p>

「プラグインでデータベーステーブルを作る」の版間の差分

提供: WordPress Codex 日本語版
移動先: 案内検索
("You have to put each field on its own line in your SQL statement." に関する対訳がなかったので追加しました。 やや跳躍した超訳なので、良い役が思いついたら誰か書き換えておいて下さい。)
(en:Creating Tables with Plugins 02:55, 13 May 2015 Charlestonsw 版を反映。kjmtshさんの御指摘( https://ja.forums.wordpress.org/topic/151155?replies=11#post-210682 )による。)
2行目: 2行目:
 
__TOC__
 
__TOC__
  
もしWordPress[[プラグインの作成]]をしているなら、WordPressデータベースになんらかの情報を保存しておきたいと思うことでしょう。保存できる情報は主に二つあります:
+
もし WordPress の[[プラグインの作成|プラグインを作成]]しているなら、WordPress データベースになんらかの情報を保存しておきたいと思うことでしょう。保存できる情報は主に二つあります:
* '''設定情報''' -- プラグインを有効化したときにユーザが最初に入力した値のこと。大幅に変更されることはあまりありません(例えば、タグ関連プラグインの場合、ユーザが選ぶのはタグ・クラウドのフォーマットぐらいです)。設定情報は通常を使って[[プラグインの作成#データベースにデータを保存する方法|WordPressの''opstions''メカニズム]]によって保存されます。
+
* '''設定情報''' -- プラグインを有効化したときにユーザが最初に入力した値のこと。大幅に変更されることはあまりありません(例えば、タグ関連プラグインの場合、ユーザが選ぶのはタグ・クラウドのフォーマットぐらいです)。<br />設定情報は通常、[[プラグインの作成#データベースにデータを保存する方法|WordPress の ''options'' メカニズム]]を使って保存されます。
* '''データ''' -- ユーザがプラグインを使い続けることで増えていく情報。通常は投稿、カテゴリー、ファイルアップロードなどのWordPressコンポーネントに関連するもの(例えば、タグ関連プラグインでは、タグ名および、タグと投稿の関連を示すデータ)です。データは通常、別のMySQLテーブルに保存されるので、新たに作る必要があります。
+
* '''データ''' -- ユーザがプラグインを使い続けることで増えていく情報。通常は投稿、カテゴリー、ファイルアップロードなどの WordPress コンポーネントに関連するもの(例えば、統計情報に関するプラグインの場合、ページ閲覧数やリファラーなどの投稿に関連する統計情報)です。<br />データは通常、別の MySQL テーブルに保存されるので、新たに作る必要があります。しかし、まったく新しいテーブルに飛びつく前に、プラグインのデータを [[プラグインの作成#データベースにデータを保存する方法|WordPress の投稿メタ]](カスタムフィールド)へ保存してうまくいくか検討してみてください。投稿メタは望ましい方法ですので、可能であり実用的なら利用してください。
  
この記事はプラグインがデータを保存するためにMySQLテーブルを自動的に作成する方法について述べています。ここに書かれている方法の他には、プラグインをインストールするとき、ユーザにインストールスクリプトを実行してもらうものがあります。もう一つの方法では、ユーザ自ら [[phpMyAdmin]]/[[:en:phpMyAdmin|en]]のようなものを使って、SQLクエリを実行してもらうという手もあります。しかし、どちらもあまり満足の行くものとはならないでしょう。ユーザはインストールスクリプトの実行やクエリの発行をよく忘れます(もしかしたらphpMyAdminを使えない環境かもしれません)。
+
この記事は、プラグインがデータを保存するために MySQL テーブルを自動的に作成する方法について説明します。ここに書かれている方法の他には、プラグインをインストールするとき、ユーザにインストールスクリプトを実行してもらうという方法があります。もう一つ、ユーザ自ら [[phpMyAdmin]]/[[:en:phpMyAdmin|en]] のようなものを使って、SQL クエリを実行してもらうという方法もあります。しかし、どちらもあまり満足のいくものとはならないでしょう。ユーザはインストールスクリプトの実行やクエリの発行をよく忘れます(もしかしたら phpMyAdmin を使えない環境かもしれません)。
  
というわけで、以下のステップに従い、プラグインにテーブルを自動生成させることをオススメします:
+
というわけで、以下のステップに従い、プラグインにテーブルを自動生成させることをオススメします:
# テーブルを生成するPHP関数を書く。
+
# テーブルを生成する PHP 関数を書く。
# プラグインが有効化されたときにWordPressがその関数を呼び出すようにする。
+
# プラグインが有効化されたときに WordPress がその関数を呼び出すようにする。
# プラグインの新しいバージョンを作成して、別のテーブル構造が必要になったらアップグレード用関数を作成する。
+
# プラグインの新しいバージョンを作成したとき、もし別のテーブル構造が必要になったら、アップグレード用関数を作成する。
  
 +
<div id="Create_Database_Tables">
 
== データベーステーブルの作成 ==
 
== データベーステーブルの作成 ==
 +
</div>
  
プラグインにデータベーステーブルを自動生成させるための第一歩は、WordPressのMySQLデータベースにテーブルを生成するPHP関数を作ることです。この記事の意図を明確にするために、<tt>jal_install</tt>関数を呼び出すことだとしましょう。
+
プラグインにデータベーステーブルを自動生成させるための第一歩は、WordPress の MySQL データベースにテーブルを追加する PHP 関数を作ることです。この記事をわかりやすくするために、その関数を <tt>jal_install</tt> という名前だとしましょう。
  
 +
<div id="Database_Table_Prefix">
 
=== データベーステーブルの接頭辞 ===
 
=== データベーステーブルの接頭辞 ===
 +
</div>
  
WordPressサイトのオーナーは<tt>wp-config.php</tt>ファイル内にデータベーステーブル接頭辞を定義できます。デフォルトだと、接頭辞は"wp_"となっていますが、そこに入る値を考えて、データベーステーブル名を定義しましょう。この値は<tt>$wpdb->prefix</tt>変数に格納されています。(もし2.0よりも古いバージョンのWordPressを使用している場合、グローバル変数<tt>$table_prefix</tt>を使う必要があります。これは2.1から削除されました。)
+
WordPress サイトのオーナーは、<tt>wp-config.php</tt> ファイル内にデータベーステーブル接頭辞を定義できます。デフォルトの接頭辞は "<tt>wp_</tt>" ですが、実際に設定されている値を使ってデータベーステーブル名を定義する必要があります。この値は <tt>$wpdb->prefix</tt> 変数に格納されています。(もし 2.0 よりも古いバージョンの WordPress を使用している場合、グローバル変数 <tt>$table_prefix</tt> を使う必要がありますが、これは 2.1 から削除されました。)
  
<tt>(prefix)liveshoutbox</tt>という名前のテーブルを作成したければ、テーブル作成関数を以下のように始めましょう:
+
さて、<tt>(prefix)liveshoutbox</tt> という名前のテーブルを作成したければ、テーブル作成関数を以下のように始めましょう:
  
 
<pre>
 
<pre>
function jal_install () {
+
function jal_install() {
  global $wpdb;
+
  global $wpdb;
  
  $table_name = $wpdb->prefix . "liveshoutbox";
+
  $table_name = $wpdb->prefix . "liveshoutbox";  
</pre>
+
}
 
+
=== テーブルは作成済み? ===
+
 
+
テーブル作成の次のステップは、テーブルがすでに作られていないかをチェックすることです。次の<tt>if</tt>節ではテーブルを発見するために<tt>SHOW TABLES</tt>SQLクエリが実行され、実行結果を作成予定のテーブル名と比較しています:
+
 
+
<pre>
+
    if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
+
 
</pre>
 
</pre>
  
 +
<div id="Creating_or_Updating_the_Table">
 
=== テーブルの作成または更新 ===
 
=== テーブルの作成または更新 ===
 +
</div>
  
次のステップでは、実際にテーブルを作成します。直接SQLクエリを実行するより、<tt>wp-admin/upgrade-functions.php</tt>(このファイルはデフォルトだと読み込まれないので、インクルードする必要があります)にある<tt>dbDelta</tt>関数を使いましょう〔訳注:バージョン2.5以降ではwp-admin/include/upgrade.phpで定義されています〕。<tt>dbDelta</tt>関数は現在のテーブル構造を走査し、作成予定のテーブルと比較、必要に応じてテーブルを追加・修正します。更新にはとても便利な関数です(<tt>dbDelta</tt>の使用例については<tt>wp-admin/upgrade-schema.php</tt>を確認のこと〔訳注:このファイルはバージョン2.7に含まれません〕)。しかしながら、<tt>dbDelta</tt>関数はやや融通がききません。こんな風にです:
+
次のステップでは、実際にテーブルを作成します。直接 SQL クエリを実行するより、<tt>wp-admin/includes/upgrade.php</tt> にある <tt>dbDelta</tt> 関数を使いましょう(このファイルはデフォルトだと読み込まれないので、インクルードする必要があります)。<tt>dbDelta</tt> 関数は現在のテーブル構造を走査し、作成予定のテーブル構造と比較します。そして、必要に応じてテーブルを追加・変更してくれるので、更新にはとても便利な関数です(<tt>dbDelta</tt> の使用例については <tt>wp-admin/includes/schema.php</tt> 参照)。'''注意''':<tt>dbDelta</tt> 関数はやや融通がききません。こんな風にです:
* 1行につき1つのフィールドを定義してください。 〔訳注:一つの行に複数のフィールド定義を書くことは出来ません。さもなくば ALTER TABLEが正しく実行されず、プラグインのバージョンアップに失敗します。 〕
+
* 1 行につき、ひとつのフィールドを定義してください。〔訳注:ひとつの行に複数のフィールド定義を書くことはできません。さもなくば ALTER TABLE が正しく実行されず、プラグインのバージョンアップに失敗します。〕
* PRIMARY KEYと主キーの定義の間には二つのスペースが必要です。〔訳注:原文 "You have to have two spaces between the words PRIMARY KEY and the definition of your primary key."〕
+
* PRIMARY KEY というキーワードと、主キーの定義の間には、二つのスペースが必要です。
* INDEXという言葉ではなく、KEYという言葉を使う必要があります。
+
* INDEX という同義語ではなく、KEY というキーワードを使う必要があります。さらに最低ひとつの KEY を含めなければなりません。
 +
* フィールド名のまわりにアポストロフィ(<tt>&#039;</tt>)やバッククォート(<tt>&#096;</tt>)を使ってはいけません。
 +
* フィールドタイプはすべて小文字であること。
 +
* SQL キーワード、例えば CREATE TABLE や UPDATE は、大文字であること。
 +
* 長さパラメータを受け付けるすべてのフィールドに長さを指定すること。例えば <tt>int(11)</tt> のように。
  
この忠告に従えって、関数に以下のような行を追加すれば、テーブルを自動生成・更新します。<tt>$sql</tt>変数にテーブル構造を代入してください。
+
この注意事項に従って、関数に以下のような行を追加すれば、テーブルを自動生成・更新します。<tt>$sql</tt> 変数に、自分が作りたいテーブル構造を代入してください。
  
 
<pre>
 
<pre>
$sql = "CREATE TABLE " . $table_name . " (
+
global $wpdb;
  id mediumint(9) NOT NULL AUTO_INCREMENT,
+
  time bigint(11) DEFAULT '0' NOT NULL,
+
  name tinytext NOT NULL,
+
  text text NOT NULL,
+
  url VARCHAR(55) NOT NULL,
+
  UNIQUE KEY id (id)
+
);";
+
  
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
+
$charset_collate = $wpdb->get_charset_collate();
dbDelta($sql);
+
 
 +
$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 );
 
</pre>
 
</pre>
  
=== 初期データを加える ===
+
'''参考''':上のコードで、テーブルのデフォルト文字セットと照合順序を指定しています。もし、これを省くと、一部の文字がテーブルへ格納されるときに <tt>?</tt> の並びへ変換されてしまう可能性があります。この例では <tt>$wpdb->get_charset_collate()</tt> 関数を使って文字セットと照合順序を取得します。この関数は WordPress 3.5 で導入されたので、以前のバージョンをサポートする必要がある場合は、文字セットと照合順序を表す文字列を自分で作る必要があります(この関数のソースコードを複製してもよいでしょう)。
  
最後に、作成したテーブルになんらかのデータを加えましょう。以下がそのやり方です:
+
<div id="Adding_Initial_Data">
 +
=== 初期データを登録する ===
 +
</div>
  
<pre>
+
最後に、作成したテーブルになんらかのデータを登録するとしましょう。下記の例がそのやり方です:
  $welcome_name = "Wordpressさん";
+
  $welcome_text = "おめでとうございます、インストールに成功しました!";
+
  
  $insert = "INSERT INTO " . $table_name .
+
<pre>
            " (time, name, text) " .
+
$welcome_name = 'Wordpress さん';
            "VALUES ('" . time() . "','" . $wpdb->escape($welcome_name) . "','" . $wpdb->escape($welcome_text) . "')";
+
$welcome_text = 'おめでとうございます、インストールに成功しました!';
  
  $results = $wpdb->query( $insert );
+
$table_name = $wpdb->prefix . 'liveshoutbox';
  
 +
$wpdb->insert(
 +
  $table_name,
 +
  array(
 +
    'time' => current_time( 'mysql' ),
 +
    'name' => $welcome_name,
 +
    'text' => $welcome_text,
 +
  )
 +
);
 
</pre>
 
</pre>
  
'''注意点:''' この関数の<tt>$welcome_name</tt><tt>$welcome_text</tt>は自ら定義したもので、SQL特殊文字が含まれていないことはわかっています。しかし、それでもデータベースに渡す前に変数に対して<tt>$wpdb->escape()</tt>関数を実行することは、セキュリティ問題と思いがけないバグを避けるために有効です。
+
'''参考''':<strong>WPDB の使い方について詳しくは [[関数リファレンス/wpdb Class|wpdb クラス]]を参照してください。</strong>
 +
今回は <tt>$wpdb->insert</tt> を使っているので、データは自動的にエスケープされます。もし <tt>$wpdb->query</tt> のような別のメソッドを使う必要がある場合は、セキュリティ問題を避けるため、クエリをデータベースへ渡す前に変数を <tt>$wpdb->prepare</tt> 関数に通すべきです。この例の関数は <tt>$welcome_name</tt> と <tt>$welcome_text</tt> を定義しており、値に SQL 特殊文字が含まれないことが分かっていますが、それでもです。
  
 +
<div id="A_Version_Option">
 
=== バージョンオプション ===
 
=== バージョンオプション ===
 +
</div>
  
データベース構造のバージョン番号を記録するオプションレコードを付け足すのもいいアイデアです。テーブルを更新するとき、この情報を使うことができます:
+
データベース構造のバージョン番号を記録するオプションを付け足すのもいいアイデアです。テーブルを更新するとき、この情報を使うことができます:
  
 
<pre>
 
<pre>
add_option("jal_db_version", "1.0");
+
add_option( "jal_db_version", "1.0" );
 
</pre>
 
</pre>
  
 +
<div id="The_Whole_Function">
 
=== 完成した関数 ===
 
=== 完成した関数 ===
 +
</div>
  
これで関数は完成しました。まとめて見てみましょう。バージョン番号がグローバル変数に格納されていることに注意してください。
+
これで関数が完成しました。まとめて見てみましょう。バージョン番号がグローバル変数に格納されていることに注意してください。
  
 
<pre>
 
<pre>
 +
<?php
  
$jal_db_version = "1.0";
+
global $jal_db_version;
 +
$jal_db_version = '1.0';
  
function jal_install () {
+
function jal_install() {
  global $wpdb;
+
  global $wpdb;
  global $jal_db_version;
+
  global $jal_db_version;
  
  $table_name = $wpdb->prefix . "liveshoutbox";
+
  $table_name = $wpdb->prefix . 'liveshoutbox';
  if($wpdb->get_var("show tables like '$table_name'") != $table_name) {
+
     
+
      $sql = "CREATE TABLE " . $table_name . " (
+
  id mediumint(9) NOT NULL AUTO_INCREMENT,
+
  time bigint(11) DEFAULT '0' NOT NULL,
+
  name tinytext NOT NULL,
+
  text text NOT NULL,
+
  url VARCHAR(55) NOT NULL,
+
  UNIQUE KEY id (id)
+
);";
+
  
      require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
+
  $charset_collate = $wpdb->get_charset_collate();
      dbDelta($sql);
+
  
      $welcome_name = "Wordpressさん";
+
  $sql = "CREATE TABLE $table_name (
      $welcome_text = "おめでとうございます、インストールに成功しました!";
+
    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;";
  
      $insert = "INSERT INTO " . $table_name .
+
  require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
            " (time, name, text) " .
+
  dbDelta( $sql );
            "VALUES ('" . time() . "','" . $wpdb->escape($welcome_name) . "','" . $wpdb->escape($welcome_text) . "')";
+
  
      $results = $wpdb->query( $insert );
+
  add_option( 'jal_db_version', $jal_db_version );
+
}
      add_option("jal_db_version", $jal_db_version);
+
 
 +
function jal_install_data() {
 +
  global $wpdb;
 +
 
 +
  $welcome_name = 'Wordpress さん';
 +
  $welcome_text = 'おめでとうございます、インストールに成功しました!';
 +
 
 +
  $table_name = $wpdb->prefix . 'liveshoutbox';
  
  }
+
  $wpdb->insert(
 +
    $table_name,
 +
    array(
 +
      'time' => current_time( 'mysql' ),
 +
      'name' => $welcome_name,
 +
      'text' => $welcome_text,
 +
    )
 +
  );
 
}
 
}
 
</pre>
 
</pre>
  
 +
<div id="Calling_the_functions">
 
== 関数を呼び出す ==
 
== 関数を呼び出す ==
 +
</div>
  
これで初期化関数を定義できたので、管理画面でプラグインが有効化されたときにWordPressがこの関数を呼び出せるようにしましょう。そのためには、<tt>activate_</tt>アクションフックを使います。もしもあなたのプラグインファイルが<tt>wp-content/plugins/plugindir/pluginfile.php</tt>ならば、プラグインのメインファイルに以下の一文を付け加えてください:
+
これで初期化用の関数を定義できたので、管理画面でプラグインが有効化されたときに WordPress がこの関数を呼び出せるようにしましょう。そのためには <tt>activate_</tt> アクションフックを使います。もしもあなたのプラグインファイルが <tt>wp-content/plugins/plugindir/pluginfile.php</tt> ならば、プラグインのメインファイルに以下の一文を付け加えてください:
  
 
<pre>
 
<pre>
register_activation_hook(__FILE__,'jal_install');
+
register_activation_hook( __FILE__, 'jal_install' );
 +
register_activation_hook( __FILE__, 'jal_install_data' );
 
</pre>
 
</pre>
  
詳しくは[[関数リファレンス/register_deactivation_hook]]/[[:en:Function Reference/register_activation_hook|en]]を見てください。
+
詳しくは <tt>[[関数リファレンス/register_activation_hook|register_activation_hook()]]</tt> を見てください。
  
==アップグレード用関数を追加する==
+
<div id="Adding_an_Upgrade_Function">
 +
== アップグレード用関数を追加する ==
 +
</div>
  
プラグインの寿命が尽きて、アップグレード版ではデータベース構造を変更する必要が出てくるかもしれません。そのためには、アップグレード用のコードをプラグインファイルに含め、それに新しいバージョンがインストールされたことを関知させ、データベース構造を更新させてなくてはいけません。一番簡単な方法は先ほど作った<tt>jal_install</tt>関数にコードを追加することです。
+
プラグインが歳をとって、アップグレード版ではプラグインのデータベース構造を変更する必要が出てくるかもしれません。そうするには、アップグレード用のコードをプラグインファイルに含め、それに新しいバージョンがインストールされたことを関知させ、データベース構造を更新させてなくてはいけません。一番簡単な方法は、先ほど作った <tt>jal_install</tt> 関数にコードを追加します。
  
この関数が呼び出しを受けることをしっかり把握しておく必要があります。したがってアップグレード時はプラグインのユーザに対して、プラグインの無効化、新しいプラグインファイルのアップロード、そしてプラグインの再有効化という手順を踏むよう教える必要があります。
+
さて、先ほどの関数が、すでにプラグインのバージョン 1.0 用のテーブルを作成するために使われたとしましょう。そして今度は、バージョン 1.1 へアップグレードして URL フィールドが広くなるとします(55 文字から 100 文字へ)。そのためには <tt>jal_install</tt> 関数の最後に以下の行を加えて、バージョンをチェックし、必要ならばアップグレードします:
 
+
さて、上記の関数はあなたのプラグイン・バージョン1.0用のテーブルを作成するために使われたといましょう。いまやバージョン1.1にアップグレードし、URLフィールドは大きくなっています(55文字から100文字へ)。<tt>jal_install</tt>関数の最後に以下の行を加えて、バージョンチェックをし、必要ならばアップグレードしましょう:
+
  
 
<pre>
 
<pre>
 +
<?php
  
  $installed_ver = get_option( "jal_db_version" );
+
global $wpdb;
 +
$installed_ver = get_option( "jal_db_version" );
  
  if( $installed_ver != $jal_db_version ) {
+
if ( $installed_ver != $jal_db_version ) {
  
      $sql = "CREATE TABLE " . $table_name . " (
+
  $table_name = $wpdb->prefix . 'liveshoutbox';
  id mediumint(9) NOT NULL AUTO_INCREMENT,
+
  time bigint(11) DEFAULT '0' NOT NULL,
+
  name tinytext NOT NULL,
+
  text text NOT NULL,
+
  url VARCHAR(100) NOT NULL,
+
  UNIQUE KEY id (id)
+
);";
+
  
      require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
+
  $sql = "CREATE TABLE $table_name (
      dbDelta($sql);
+
    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(100) DEFAULT '' NOT NULL,
 +
    UNIQUE KEY id (id)
 +
  );";
  
      update_option( "jal_db_version", $jal_db_version );
+
  require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
  }
+
  dbDelta( $sql );
 +
 
 +
  update_option( "jal_db_version", $jal_db_version );
 +
}
 
</pre>
 
</pre>
  
ファイルの最初にあるグローバル変数<tt>$jal_db_version</tt>も変更する必要があります。もちろん、新しいテーブル構造を作るために上で作られた初期化部分にも変更を加える必要があります。
+
ファイルの最初にあるグローバル変数 <tt>$jal_db_version</tt> も変更する必要があります。もちろん、初期化用の関数も、新しいテーブル構造を扱えるように変更しなければならないでしょう。
 +
 
 +
WordPress バージョン 3.1 から、<tt>[[関数リファレンス/register_activation_hook|register_activation_hook()]]</tt> で登録された初期化用の関数は、プラグインの更新時に呼び出されなくなりました。従って、プラグインをアップグレードした後に上記のコードを実行するには、プラグインのデータベースバージョンを別のフックでチェックする必要があります。そしてデータベースバージョンが古ければ関数を呼び出します。次のようなやり方です:
 +
 
 +
<pre>
 +
function myplugin_update_db_check() {
 +
  global $jal_db_version;
 +
  if ( get_site_option( 'jal_db_version' ) != $jal_db_version ) {
 +
    jal_install();
 +
  }
 +
}
 +
add_action( 'plugins_loaded', 'myplugin_update_db_check' );
 +
</pre>
  
== 関連情報 ==
+
<div id="Resources">
 +
== 関連項目 ==
 +
</div>
  
プラグイン開発に関してのより詳しい情報は、プラグイン開発情報の理解を助ける[[Plugin Resources|プラグイン・リソース]]を見てください。[[Mailing Lists#Hackers|wp-hackers メーリングリスト]]/[[:en:Mailing Lists#Hackers|en]]にある記事も助けになるでしょう:[http://comox.textdrive.com/pipermail/wp-hackers/2005-May/000940.html WordPress Hackers Mailing List: Answer to Plugin Requires Additional Tables]
+
プラグイン開発についてもっと詳しい情報は、様々な情報をカバーした [[Plugin Resources|プラグイン・リソース]] を見てください。[[Mailing Lists#Hackers|wp-hackers メーリングリスト]] にある記事も助けになるでしょう: [http://lists.automattic.com/pipermail/wp-hackers/2005-May/000940.html WordPress Hackers Mailing List: Answer to Plugin Requires Additional Tables]。これもどうぞ: [http://wordpress.stackexchange.com/questions/4852/post-meta-vs-seperate-database-tables Post meta vs separate database tables]。
  
{{原文|Creating Tables with Plugins|56018}}<!-- 16:13, April 5, 2008 Scribu 版 -->
+
{{原文|Creating Tables with Plugins|151567}} <!-- 02:55, 13 May 2015 Charlestonsw 版 -->
  
 +
{{DEFAULTSORT:Creating Tables with Plugins}}
 
[[Category:上級トピック]]
 
[[Category:上級トピック]]
 
[[Category:WordPress の開発]]
 
[[Category:WordPress の開発]]
182行目: 234行目:
  
 
[[en:Creating Tables with Plugins]]
 
[[en:Creating Tables with Plugins]]
 +
[[ru:Плагины: создание таблиц БД]]

2015年5月30日 (土) 18:37時点における版

ページ名検討中: このページ名「プラグインでデータベーステーブルを作る」について改名が提案されています。ご意見をお寄せください。

もし WordPress のプラグインを作成しているなら、WordPress データベースになんらかの情報を保存しておきたいと思うことでしょう。保存できる情報は主に二つあります:

  • 設定情報 -- プラグインを有効化したときにユーザが最初に入力した値のこと。大幅に変更されることはあまりありません(例えば、タグ関連プラグインの場合、ユーザが選ぶのはタグ・クラウドのフォーマットぐらいです)。
    設定情報は通常、WordPress の options メカニズムを使って保存されます。
  • データ -- ユーザがプラグインを使い続けることで増えていく情報。通常は投稿、カテゴリー、ファイルアップロードなどの WordPress コンポーネントに関連するもの(例えば、統計情報に関するプラグインの場合、ページ閲覧数やリファラーなどの投稿に関連する統計情報)です。
    データは通常、別の MySQL テーブルに保存されるので、新たに作る必要があります。しかし、まったく新しいテーブルに飛びつく前に、プラグインのデータを WordPress の投稿メタ(カスタムフィールド)へ保存してうまくいくか検討してみてください。投稿メタは望ましい方法ですので、可能であり実用的なら利用してください。

この記事は、プラグインがデータを保存するために MySQL テーブルを自動的に作成する方法について説明します。ここに書かれている方法の他には、プラグインをインストールするとき、ユーザにインストールスクリプトを実行してもらうという方法があります。もう一つ、ユーザ自ら phpMyAdmin/en のようなものを使って、SQL クエリを実行してもらうという方法もあります。しかし、どちらもあまり満足のいくものとはならないでしょう。ユーザはインストールスクリプトの実行やクエリの発行をよく忘れます(もしかしたら phpMyAdmin を使えない環境かもしれません)。

というわけで、以下のステップに従い、プラグインにテーブルを自動生成させることをオススメします:

  1. テーブルを生成する PHP 関数を書く。
  2. プラグインが有効化されたときに WordPress がその関数を呼び出すようにする。
  3. プラグインの新しいバージョンを作成したとき、もし別のテーブル構造が必要になったら、アップグレード用関数を作成する。

データベーステーブルの作成

プラグインにデータベーステーブルを自動生成させるための第一歩は、WordPress の MySQL データベースにテーブルを追加する PHP 関数を作ることです。この記事をわかりやすくするために、その関数を jal_install という名前だとしましょう。

データベーステーブルの接頭辞

WordPress サイトのオーナーは、wp-config.php ファイル内にデータベーステーブル接頭辞を定義できます。デフォルトの接頭辞は "wp_" ですが、実際に設定されている値を使ってデータベーステーブル名を定義する必要があります。この値は $wpdb->prefix 変数に格納されています。(もし 2.0 よりも古いバージョンの WordPress を使用している場合、グローバル変数 $table_prefix を使う必要がありますが、これは 2.1 から削除されました。)

さて、(prefix)liveshoutbox という名前のテーブルを作成したければ、テーブル作成関数を以下のように始めましょう:

function jal_install() {
  global $wpdb;

  $table_name = $wpdb->prefix . "liveshoutbox"; 
}

テーブルの作成または更新

次のステップでは、実際にテーブルを作成します。直接 SQL クエリを実行するより、wp-admin/includes/upgrade.php にある dbDelta 関数を使いましょう(このファイルはデフォルトだと読み込まれないので、インクルードする必要があります)。dbDelta 関数は現在のテーブル構造を走査し、作成予定のテーブル構造と比較します。そして、必要に応じてテーブルを追加・変更してくれるので、更新にはとても便利な関数です(dbDelta の使用例については wp-admin/includes/schema.php 参照)。注意dbDelta 関数はやや融通がききません。こんな風にです:

  • 1 行につき、ひとつのフィールドを定義してください。〔訳注:ひとつの行に複数のフィールド定義を書くことはできません。さもなくば ALTER TABLE が正しく実行されず、プラグインのバージョンアップに失敗します。〕
  • PRIMARY KEY というキーワードと、主キーの定義の間には、二つのスペースが必要です。
  • INDEX という同義語ではなく、KEY というキーワードを使う必要があります。さらに最低ひとつの KEY を含めなければなりません。
  • フィールド名のまわりにアポストロフィ(')やバッククォート(`)を使ってはいけません。
  • フィールドタイプはすべて小文字であること。
  • SQL キーワード、例えば CREATE TABLE や UPDATE は、大文字であること。
  • 長さパラメータを受け付けるすべてのフィールドに長さを指定すること。例えば int(11) のように。

この注意事項に従って、関数に以下のような行を追加すれば、テーブルを自動生成・更新します。$sql 変数に、自分が作りたいテーブル構造を代入してください。

global $wpdb;

$charset_collate = $wpdb->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 );

参考:上のコードで、テーブルのデフォルト文字セットと照合順序を指定しています。もし、これを省くと、一部の文字がテーブルへ格納されるときに ? の並びへ変換されてしまう可能性があります。この例では $wpdb->get_charset_collate() 関数を使って文字セットと照合順序を取得します。この関数は WordPress 3.5 で導入されたので、以前のバージョンをサポートする必要がある場合は、文字セットと照合順序を表す文字列を自分で作る必要があります(この関数のソースコードを複製してもよいでしょう)。

初期データを登録する

最後に、作成したテーブルになんらかのデータを登録するとしましょう。下記の例がそのやり方です:

$welcome_name = 'Wordpress さん';
$welcome_text = 'おめでとうございます、インストールに成功しました!';

$table_name = $wpdb->prefix . 'liveshoutbox';

$wpdb->insert(
  $table_name,
  array(
    'time' => current_time( 'mysql' ),
    'name' => $welcome_name,
    'text' => $welcome_text,
  ) 
);

参考WPDB の使い方について詳しくは wpdb クラスを参照してください。 今回は $wpdb->insert を使っているので、データは自動的にエスケープされます。もし $wpdb->query のような別のメソッドを使う必要がある場合は、セキュリティ問題を避けるため、クエリをデータベースへ渡す前に変数を $wpdb->prepare 関数に通すべきです。この例の関数は $welcome_name$welcome_text を定義しており、値に SQL 特殊文字が含まれないことが分かっていますが、それでもです。

バージョンオプション

データベース構造のバージョン番号を記録するオプションを付け足すのもいいアイデアです。テーブルを更新するとき、この情報を使うことができます:

add_option( "jal_db_version", "1.0" );

完成した関数

これで関数が完成しました。まとめて見てみましょう。バージョン番号がグローバル変数に格納されていることに注意してください。

<?php

global $jal_db_version;
$jal_db_version = '1.0';

function jal_install() {
  global $wpdb;
  global $jal_db_version;

  $table_name = $wpdb->prefix . 'liveshoutbox';

  $charset_collate = $wpdb->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 );

  add_option( 'jal_db_version', $jal_db_version );
}

function jal_install_data() {
  global $wpdb;

  $welcome_name = 'Wordpress さん';
  $welcome_text = 'おめでとうございます、インストールに成功しました!';

  $table_name = $wpdb->prefix . 'liveshoutbox';

  $wpdb->insert(
    $table_name,
    array(
      'time' => current_time( 'mysql' ),
      'name' => $welcome_name,
      'text' => $welcome_text,
    )
  );
}

関数を呼び出す

これで初期化用の関数を定義できたので、管理画面でプラグインが有効化されたときに WordPress がこの関数を呼び出せるようにしましょう。そのためには activate_ アクションフックを使います。もしもあなたのプラグインファイルが wp-content/plugins/plugindir/pluginfile.php ならば、プラグインのメインファイルに以下の一文を付け加えてください:

register_activation_hook( __FILE__, 'jal_install' );
register_activation_hook( __FILE__, 'jal_install_data' );

詳しくは register_activation_hook() を見てください。

アップグレード用関数を追加する

プラグインが歳をとって、アップグレード版ではプラグインのデータベース構造を変更する必要が出てくるかもしれません。そうするには、アップグレード用のコードをプラグインファイルに含め、それに新しいバージョンがインストールされたことを関知させ、データベース構造を更新させてなくてはいけません。一番簡単な方法は、先ほど作った jal_install 関数にコードを追加します。

さて、先ほどの関数が、すでにプラグインのバージョン 1.0 用のテーブルを作成するために使われたとしましょう。そして今度は、バージョン 1.1 へアップグレードして URL フィールドが広くなるとします(55 文字から 100 文字へ)。そのためには jal_install 関数の最後に以下の行を加えて、バージョンをチェックし、必要ならばアップグレードします:

<?php

global $wpdb;
$installed_ver = get_option( "jal_db_version" );

if ( $installed_ver != $jal_db_version ) {

  $table_name = $wpdb->prefix . 'liveshoutbox';

  $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(100) DEFAULT '' NOT NULL,
    UNIQUE KEY id (id)
  );";

  require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
  dbDelta( $sql );

  update_option( "jal_db_version", $jal_db_version );
}

ファイルの最初にあるグローバル変数 $jal_db_version も変更する必要があります。もちろん、初期化用の関数も、新しいテーブル構造を扱えるように変更しなければならないでしょう。

WordPress バージョン 3.1 から、register_activation_hook() で登録された初期化用の関数は、プラグインの更新時に呼び出されなくなりました。従って、プラグインをアップグレードした後に上記のコードを実行するには、プラグインのデータベースバージョンを別のフックでチェックする必要があります。そしてデータベースバージョンが古ければ関数を呼び出します。次のようなやり方です:

function myplugin_update_db_check() {
  global $jal_db_version;
  if ( get_site_option( 'jal_db_version' ) != $jal_db_version ) {
    jal_install();
  }
}
add_action( 'plugins_loaded', 'myplugin_update_db_check' );

関連項目

プラグイン開発についてもっと詳しい情報は、様々な情報をカバーした プラグイン・リソース を見てください。wp-hackers メーリングリスト にある記事も助けになるでしょう: WordPress Hackers Mailing List: Answer to Plugin Requires Additional Tables。これもどうぞ: Post meta vs separate database tables

最新英語版: WordPress Codex » Creating Tables with Plugins最新版との差分