如果你正在制作wordpress插件,你很可能需要向wordpress数据库中存储一些信息。需要存储的信息有两种:
- 设置信息 — 用户初次使用你的插件时输入的选项,这些信息基本不会增长(例如tag-related插件,用户需要设置tag的样式选项)。设置信息一般会使用WordPress options mechanism来存储。
- 数据 — 用户在使用插件时会不断增加的信息,例如与文章、分类、附件或其他WordPress组件有关的信息。这样的数据可以存储在单独创建的MySQL表中。在创建新表前,你也可以试试把数据存储到WordPress’ Post Meta中,如果Post Meta可以满足你的要求的话,应该优先考虑使用这种方法。
这篇文章介绍了怎样使你的插件自动创建一个MySQL表格来存储它的数据。除了这里介绍的方法,也可以让插件用户在安装你的插件时运行一个安装脚本 来创建数据库,或者用户在数据库中自己执行一段SQL查询。但是这两种方法都不完美,用户很可能忘记运行安装脚本或者是SQL查询。
所以,推荐你使用下面的步骤来使你的插件自动创建数据库表:
- 使用一个PHP函数来创建表格。
- 确保当插件启用时WordPress会调用这个函数。
- 建立一个升级函数,当新版本的插件表结构发生变化时会用到这个升级函数。
建立数据库表格
要使你的插件自动创建数据库表,第一步是在你的插件中建立一个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');