用插件创建数据库表

0条评论

开发WordPress插件时,我们会发现自己需要在WordPress数据库中存入一些信息。下面是两种常见的信息存入方法:

  • 设置信息——即我们首次设置插件时的设置记录,但设置记录只包括插件的相关功能设置,其它设置不在此“设置信息”范围内。我们通常用WordPress选项系统来保存设置信息。
  • 数据——用户使用我们的插件时在插件中不断加入的信息,这些信息主要是关于日志、类别、上传以及其它WordPress组件的扩展信息(例如在一个数据统计相关插件中,“数据”包括各个页面的页面浏览量、反向链接个数以及其它日志相关统计信息)。我们可以新建一个MySQL表,把数据存入这个表。创建新数据库表前,我们可以先考虑把插件数据存入WordPress的日志元(又名“自定义域”)。如果可能,首选方法是把插件数据存入日志元。

本文简要说明了让插件自动创建MySQL表以存储插件信息的方法。注意,我们可以在用户下载我们的插件时提供一个安装脚本,用户可以运行这个脚本来代替下面将要介绍的方法。另一个方法是让用户用PhpMyAdmin执行某个SQL语句。但这两种方法效果不尽如人意,因为用户很容易忘记安装脚本,也不能很好地执行语句查询(或许他们甚至没有可用的phpMyAdmin)。

基于以上情况,我们可以根据以下操作,让插件自动创建数据库表:

1. 编写一个创建表的PHP函数

2. 确保插件被激活时WordPress会调用之前创建的函数

3. 如果插件发布新版本时结构有所调整,还需要创建一个升级函数

创建数据库表

第一步,我们需要在插件中创建一个能在WordPress MySQL数据库中添加一个或多个数据库表的PHP函数。为方便展开说明,我们假设函数名称为jal_install。

数据库表前缀

WordPress博客主人可以在wp-config.php文件中定义一个数据库表前缀。WordPress数据库默认表前缀是"wp_",但我们可以检查实际值并用该值来定义数据库表名。可以在$wpdb->prefix变量中查找该实际值。(在早于WordPress 2.0的WordPress版本中开发插件时,需要用到table_prefix全局变量。该变量在WordPress 2.1中停用。)

因此,如果我们需要创建一个名为(前缀)liveshoutbox的数据库表,首先要将建表函数的前几行代码写成以下样式:

function jal_install () {
   global $wpdb;

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

我们需要的数据库表是否已经存在?

之后我们需要检查数据库中是不是已经有一个我们需要的表。下面的if语句利用SHOW TABLES SQL查询语句来查找可能符合我们需要的数据库表,将查找出的表与我们的表名进行对比:

    if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {  

创建表与升级表

接下来我们就要实际创建数据库表了。这里会用到wp-admin/upgrade-functions.php(该文件不是WordPress默认加载文件,因此我们要自己手动加载此文件)中的dbDelta函数而不是直接执行SQL语句。dbDelta函数会检查现有表结构并将该表结构和我们需要的表结构进行对比,之后对现有表结构进行必要添加和修改,以便升级(更多dbDelta用法示例可参见 wp-admin/upgrade-schema.php )。注意,使用dbDelta函数时要求较严格,使用时请注意以下几点:

  • 将所有字段放在SQL语句的与字段相对应的位置上
  • RIMARY KEY之间要用空格隔开,定义主关键字时也应用空格隔开
  • 使用关键字KEY而不是其同义词INDEX

根据以上说明,我们编写出函数之后部分代码,也就是实际创建/升级数据库表的代码部分。我们还需要在$sql变量中替换自己的表结构:

$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');
dbDelta($sql);

添加初始数据

最后我们要为数据库表加入之前创建的数据。下面是加入数据示例:

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

  $insert = "INSERT INTO " . $table_name .
            " (time, name, text) " .
            "VALUES ('" . time() . "','" . $wpdb->escape($welcome_name) . "','" . $wpdb->escape($welcome_text) . "')";

  $results = $wpdb->query( $insert );

注意:即使在函数中定义了$welcome_name 和$welcome_text参数,并且这两个参数中没有特别的SQL字符,但我们仍然需要在将 $wpdb->escape传递到数据库前运行变量,以预防潜在的安全问题和BUG。

版本选择

为数据库表加上一个版本号记录选项来记录数据库表结构也是个很好的主意。需要升级数据库表时我们就会用到所记录的信息:

add_option("jal_db_version", "1.0");  

完整的函数

至此,建表函数编写完毕。注意,此时版本号被存储在某个全局变量中。

$jal_db_version = "1.0";

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

   $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');
      dbDelta($sql);

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

      $insert = "INSERT INTO " . $table_name .
            " (time, name, text) " .
            "VALUES ('" . time() . "','" . $wpdb->escape($welcome_name) . "','" . $wpdb->escape($welcome_text) . "')";

      $results = $wpdb->query( $insert );
 
      add_option("jal_db_version", $jal_db_version);

   }
}

调用函数

定义初始函数后,我们需要确保WordPress管理用户激活插件时WordPress会调用我们所定义的函数。这时需要用到activate_ action钩子。如果插件文件是wp-content/plugins/plugindir/pluginfile.php,我们可以把下面这行代码放入插件主体文件:

register_activation_hook(__FILE__,'jal_install');  

详细信息见常用函数-register_activation_hook()

添加升级函数

升级自己所开发的插件时首先要在插件中生成更新代码,用这些代码来检测新版本的存在,有的话则升级数据库结构。最简单的方法是将代码加入我们之前创建的jal_install函数。

注意,我们一定要确保函数会被WordPress调用。因此我们需要让插件用户明白,当他们升级插件时,首先要禁用插件,将新的插件文件复制到原有插件文件中,然后再激活插件。

假设之前创建的jal_install函数用于创建插件1.0的数据库,而现在我们要将插件升级到1.0版,这样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 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');
      dbDelta($sql);

      update_option( "jal_db_version", $jal_db_version );
  }

我们要修改文件顶端的全局变量$jal_db_version,此外,如果要使用新的数据库表结构,我们还需要更改之前创建的代码初始部分。