如果你正在制作wordpress插件,你很可能需要向wordpress数据库中存储一些信息。需要存储的信息有两种:

  • 设置信息 — 用户初次使用你的插件时输入的选项,这些信息基本不会增长(例如tag-related插件,用户需要设置tag的样式选项)。设置信息一般会使用WordPress options mechanism来存储。
  • 数据 — 用户在使用插件时会不断增加的信息,例如与文章、分类、附件或其他WordPress组件有关的信息。这样的数据可以存储在单独创建的MySQL表中。在创建新表前,你也可以试试把数据存储到WordPress’ Post Meta中,如果Post Meta可以满足你的要求的话,应该优先考虑使用这种方法。

这篇文章介绍了怎样使你的插件自动创建一个MySQL表格来存储它的数据。除了这里介绍的方法,也可以让插件用户在安装你的插件时运行一个安装脚本 来创建数据库,或者用户在数据库中自己执行一段SQL查询。但是这两种方法都不完美,用户很可能忘记运行安装脚本或者是SQL查询。

所以,推荐你使用下面的步骤来使你的插件自动创建数据库表:

  1. 使用一个PHP函数来创建表格。
  2. 确保当插件启用时WordPress会调用这个函数。
  3. 建立一个升级函数,当新版本的插件表结构发生变化时会用到这个升级函数。

建立数据库表格

要使你的插件自动创建数据库表,第一步是在你的插件中建立一个PHP函数,用于向WordPress数据库中建立一个或多个表格。在这里,我们假设你建立的这个函数名是“jal_install”。

数据库表前缀

WordPress站点可以在配置文件“wp-config.php”中定义数据库表前缀,默认前缀是“wp_”,但是你需要在程序中取到实际设置的前缀,并用它来创建你的表格。变量$wpdb->prefix记录了前缀的值。(WordPress 2.0及以前的版本使用全局变量$table_prefix来存储表格前缀)。

所以,如果你想创建一个名称为“前缀liveshoutbox”的表,代码的开头应该这样写:

function jal_install () {
   global $wpdb;

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

建立和更新表格

下一步就要创建数据库表了。我们需要使用函数“dbDelta”,这个函数在文件“wp-admin/includes/upgrade.php”中(我们需要在代码中包含这个文件)。函数dbDelta会检查当前表的结构,并比较与提交的请求相比较,来决定增加或者修改表结构,所以它可以很方便的更新表格结构(在文件“wp-admin/upgrade-schema.php”中有更多如何使用dbDelta的例子)。注意dbDelta函数是非常挑剔的:

  • 在SQL语句中每个字段必须独占一行;
  • 在“PRIMARY KEY”和你定义的主键名称之间必须有两个空格;
  • 必须使用“KEY”来定义关键字,而不能使用“INDEX”,并且一个表中至少要有一个关键字。

因此我们使用下面的代码来实际创建或更新表。你需要用自己的表格结构来替换$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)
 );";

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

添加初始化数据

最后,你可能需要向刚刚创建的表中添加一些数据。下面是示例代码:

$welcome_name = "Mr. WordPress";
$welcome_text = "Congratulations, you just completed the installation!";

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

注意:即使我们在这个函数中定义的变量$welcome_name和$welcome_text中没有包含SQL特殊字符,但是我们最好还是使用函数$wpdb->escape来转换一下,确保向数据库提交的数据没有安全问题或这其它问题。你可以使用$wpdb->prepare函数,或者我们使用$wpdb->insert。关于WPDB的更多用法请查看Function_Reference/wpdb_Class

版本设置

另一个好主意是添加一个设置来记录你的数据库表的版本号,以后你在更新数据库时可以使用它。

add_option("jal_db_version", "1.0");

全部函数代码

这个函数到此已经完成。让我们来看看全部的代码。注意版本号现在存储在一个全局变量中。

global $jal_db_version;
$jal_db_version = "1.0";

function jal_install() {
global $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(55) DEFAULT '' NOT NULL,
UNIQUE KEY id (id)
);";

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

add_option("jal_db_version", $jal_db_version);
}

function jal_install_data() {
$welcome_name = "Mr. WordPress";
$welcome_text = "Congratulations, you just completed the installation!";

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

调用函数

现在我们已经编写好了函数,我们需要函数在用户启用插件时被WordPress调用,因此我们需要使用activate_ action钩子,假设你的插件文件为wp-content/plugins/plugindir/pluginfile.php,将下面两行代码加入你的插件主文件中:

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

可以来这里查看register_activation_hook的更多说明Function_Reference/register_activation_hook

添加升级函数

在你的插件使用过程中,某个升级版本或许需要改变插件数据库结构。为实现这个目的,你需要创建一段升级代码来检测是否有新版本被安装,并且升级数据库。我们需要做的仅仅是把代码添加到刚才创建的jal_install函数中。

假设上面的函数是用于创建1.0版本插件数据库,现在需要升级到1.1版本,字段URL长度从55变为100。你需要把下面的代码加到jal_install函数最后,来检查程序版本或者升级:

$installed_ver = get_option( "jal_db_version" );

if( $installed_ver != $jal_db_version ) {

$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的值,同样需要使用新的数据库结构来更改上面的初始化部分代码。

从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');
- EOF -