REGISTER_ACTIVATION_HOOK未将表添加到数据库

时间:2017-04-03 作者:ExcellentSP

我已经启动了第一个插件,需要将API调用返回的值存储到数据库中。但在此之前,我需要能够创建一个数据库表。我在主插件文件所需的文件中有以下代码:

register_activation_hook(__FILE__, \'PLUGIN_activation\');
function PLUGIN_activation() {
    //setup DB Tables
    global $wpdb;

    $table_name = $wpdb->prefix . "table_name";//insert actual tablename here

    $charset_collate = $wpdb->get_charset_collate();

    $sql = "CREATE TABLE $table_name (
      id mediumint(9) NOT NULL AUTO_INCREMENT,
      event_id text NOT NULL,
      event_date mediumint(8) DEFAULT \'00000000\' NOT NULL,
      event_unique mediumint(13) NOT NULL,
      name tinytext NOT NULL,
      PRIMARY KEY  (id)
    ) $charset_collate;";

    require_once( ABSPATH . \'wp-admin/includes/upgrade.php\' );
    dbDelta( $sql );
}
我已经重新安装并激活了插件,但什么都没发生。

由于某些原因,未创建表。是什么阻止了这一切?

1 个回复
最合适的回答,由SO网友:birgire 整理而成

请注意$file 在里面register_activation_hook( $file, $callback ), 应该等于主插件文件的路径,但当您将其作为__FILE__ 那就不一样了!这意味着永远不会调用您的回调。

我还建议在函数名称前加前缀,以避免可能的名称冲突或使用名称空间。

法典中的更多内容here.

Update

深入了解函数的定义有助于提供信息:

/**
 * Set the activation hook for a plugin.
 *
 * When a plugin is activated, the action \'activate_PLUGINNAME\' hook is
 * called. In the name of this hook, PLUGINNAME is replaced with the name
 * of the plugin, including the optional subdirectory. For example, when the
 * plugin is located in wp-content/plugins/sampleplugin/sample.php, then
 * the name of this hook will become \'activate_sampleplugin/sample.php\'.
 *
 * When the plugin consists of only one file and is (as by default) located at
 * wp-content/plugins/sample.php the name of this hook will be
 * \'activate_sample.php\'.
 *
 * @since 2.0.0
 *
 * @param string   $file     The filename of the plugin including the path.
 * @param callable $function The function hooked to the \'activate_PLUGIN\' action.
 */
function register_activation_hook($file, $function) {
    $file = plugin_basename($file);
    add_action(\'activate_\' . $file, $function);
}
这是对应的do_action 在中调用插件acitvationactivate_plugin() 功能:

/**
 * Fires as a specific plugin is being activated.
 *
 * This hook is the "activation" hook used internally by register_activation_hook().
 * The dynamic portion of the hook name, `$plugin`, refers to the plugin basename.
 *
 * If a plugin is silently activated (such as during an update), this hook does not fire.
 *
 * @since 2.0.0
 *
 * @param bool $network_wide Whether to enable the plugin for all sites in the network
 *                           or just the current site. Multisite only. Default is false.
 */
  do_action( "activate_{$plugin}", $network_wide );

Example

让我们通过一个真正的插件来了解这一点。

因此,以WooCommerce插件为例,该插件具有主插件文件:

/full/path/to/wp-content/woocommerce/woocommerce.php 
它在哪里defines:

register_activation_hook( __FILE__, array( \'WC_Install\', \'install\' ) );
在哪里$file__FILE__

/full/path/to/wp-content/woocommerce/woocommerce.php 
然后线路:

$file = plugin_basename( $file );
成为:

$file = plugin_basename( \'/full/path/to/wp-content/woocommerce/woocommerce.php\' );
这就产生了:

$file = \'woocommerce/woocommerce.php\';
然后动态挂钩:

add_action(\'activate_\' . $file, $function);
生成:

add_action(\'activate_woocommerce/woocommerce.php\', $function);
因此,如果WooCommerce将注册激活挂钩放在一个特殊文件中,例如。

/full/path/to/wp-content/woocommerce/include/activation.php
那么这就是__FILE__ 我们将注册以下操作:

add_action(\'activate_woocommerce/include/activation.php\', $function);
但是没有do_action() 打电话叫那个。

相反,他们可能存储主插件文件路径,以便在其他地方使用,就像他们在主插件文件中所做的那样here:

$this->define( \'WC_PLUGIN_FILE\', __FILE__ );
希望有帮助!

相关推荐

无法在模板函数.php中使用IS_HOME

我试图在标题中加载一个滑块,但只在主页上加载。如果有帮助的话,我正在使用Ultralight模板。我正在尝试(在template functions.php中)执行以下操作:<?php if ( is_page( \'home\' ) ) : ?> dynamic_sidebar( \'Homepage Widget\' ); <?php endif; ?> 但这行不通。现在,通过快速的google,我似乎需要将请