如何实现修改数据库的WordPress插件更新?


10

我开发了一个WordPress插件,它有几个自己的数据库表。该插件在激活时创建这些表,并在删除/卸载时将其删除。

我必须实现插件的更新过程,以更新插件的代码以及表结构。最简单的情况是将新列添加到表之一。更复杂的情况是创建新的表结构并相应地更新内容。

您将如何建议解决此问题?有内置的WordPress功能可能会有所帮助吗?

Answers:


4

如今,正确的做法是将架构作为文件包含在插件源中,并使用该方案根据需要使用内置的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并不总是在更新插件时运行激活钩子(特别是,如果从“仪表板更新”页面进行了批量更新)。


这些天来,我开始从schema.sql文件的修改时间开始获取数据库的版本。这意味着仅更新scheme.sql文件就足以导致数据库升级。无需记住编辑数据库版本。类似于:$ db_version = filemtime(“ schema.sql”);
Brian C

1
那么,如果文件时间从移动服务器之类的外部设备发生变化,则mtime和db版本会发生变化吗?
沃尔夫,

文件时间始终是格林尼治标准时间(GMT),并且服务器之间的差异很少会相差几秒钟,因此几乎不可能触发两次。但是,即使再次触发它,也不会造成任何危害,因为它只运行一次并与实时数据库进行比较,显然不会更改任何内容。这是dbDelta()的妙处-它可以多次运行而不会出现问题。好问题,谢谢。
Brian C

3

简而言之,是- $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其删除(在执行操作之前先检查它们是否存在)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.