我开发了一个WordPress插件,它有几个自己的数据库表。该插件在激活时创建这些表,并在删除/卸载时将其删除。
我必须实现插件的更新过程,以更新插件的代码以及表结构。最简单的情况是将新列添加到表之一。更复杂的情况是创建新的表结构并相应地更新内容。
您将如何建议解决此问题?有内置的WordPress功能可能会有所帮助吗?
我开发了一个WordPress插件,它有几个自己的数据库表。该插件在激活时创建这些表,并在删除/卸载时将其删除。
我必须实现插件的更新过程,以更新插件的代码以及表结构。最简单的情况是将新列添加到表之一。更复杂的情况是创建新的表结构并相应地更新内容。
您将如何建议解决此问题?有内置的WordPress功能可能会有所帮助吗?
Answers:
如今,正确的做法是将架构作为文件包含在插件源中,并使用该方案根据需要使用内置的WordPress函数dbDelta()更新数据库。所需的实际代码非常简单:
$sql = file_get_contents( plugin_dir_path(__FILE__) . "/schema.sql" );
dbDelta( $sql );
这将根据需要为您创建和更新数据库。上次检查时,它没有删除未使用的旧列,因此您需要通过版本检查对此进行编码。这是WordPress的一个美丽功能,并且节省了大量时间。当创建schema.sql文件时要当心,您复制mysql模式导出中的间隔完全与dbDelta()代码对间隔非常挑剔有关。您还应该测试数据库的版本,如果不是最新版本,请致电上述版本以更新数据库。您可能还需要进行特定的更新,以涵盖dbDelta()无法正确进行的更改(例如,删除列)。编写简单的逻辑if测试可以很容易地进行测试,以查看版本是否已更新,并通过$ wpdb进行这些手动更新。例如,您可以删除一列现在未使用的列。
$installed_ver = get_option(MY_DB_VERSION);
$wpp = $wpdb->prefix . "mypluginname";
if ($installed_ver < 102)
$wpdb->query("ALTER TABLE ${wpp}_movies DROP nft_date");
if ($installed_ver < 107)
$wpdb->query("ALTER TABLE ${wpp}_movies CHANGE lastupdated "
. "lastupdated TIMESTAMP on update CURRENT_TIMESTAMP "
. "NOT NULL DEFAULT CURRENT_TIMESTAMP");
update_option(MY_DB_VERSION, $db_version);
如果从简化代码发布的过程中破坏了代码,则可以从运行代码和歉意中简化。
另外请记住,从WordPress 3.9.2开始,WordPress并不总是在更新插件时运行激活钩子(特别是,如果从“仪表板更新”页面进行了批量更新)。
简而言之,是- $wpdb
类。有关更多信息,请参见Codex。
每当您与自定义表(或任何表)进行交互时,都应仔细检查$wpdb
-特别是确保您熟悉prepare
可以帮助转义查询并防止注入的方法。
您应该已经很熟悉了,因为您应该使用它来创建表。在安装挂钩上,您应该具有以下内容:
$charset_collate = '';
if ( ! empty($wpdb->charset) )
$charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
if ( ! empty($wpdb->collate) )
$charset_collate .= " COLLATE $wpdb->collate";
//Create custom table
$sql_custom_table ="CREATE TABLE {$wpdb->prefix}my_table (
id bigint(20) unsigned NOT NULL auto_increment,
column_a varchar(255) default NULL,
column_b varchar(255) default NULL,
PRIMARY KEY (id)
) $charset_collate; ";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql_custom_table);
只要激活了插件(即不只是安装插件),该代码实际上就会运行。因此,它将在有人自动更新插件时运行。注意:如果他们通过手动更换插件进行升级-则不会-因此您需要admin_init
在升级插件时触发上述代码(将版本号存储在选项表中,对照当前版本进行检查) 。
现在,您通常不希望CREATE TABLE
每次更新插件时都运行SQL命令-这就是其中dBDelta()
的内容。
在运行上述命令之前-它检查表是否存在。此外,它还会检查列类型。因此,如果表不存在,则会创建它,如果确实存在,但是某些列类型已更改,则会更新它们,如果一列不存在,则会添加它。
不幸的是-如果您从上面删除一列,它不会自动删除该列。要删除列/表,您需要专门将DROP
其删除(在执行操作之前先检查它们是否存在)。