Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I've written a simple Wordpress plugin to create a new database table. The new table ought to be created when the plugin is activated. When I try to activate the plugin, I get the following error:

The plugin generated 3989 characters of unexpected output during activation. If you notice “headers already sent” messages, problems with syndication feeds or other issues, try deactivating or removing this plugin.

emphasized text This is obviously a result of the fact the $wbdb is not defined. xDebug outputs the following:

[Mon Feb 04 ] [error] PHP Notice:  Undefined variable: wpdb in test.php on line 13

The entire plugin consists of the following:

<?php

/**
 * Plugin Name: Test Plugin
 * Plugin URI: http://everybytcaptive.com
 * Description: A test plugin.
 * Version: 1.0
 * Author: Christopher Green
 * Author URI: http://everybytecaptive.com
 */

$test_db_name = $wpdb->prefix . 'test_db_name';

function test_install_plugin() {
    global $wpdb;
    global $test_db_name;

    $sql = "CREATE TABLE " . $test_db_name . " (
        `id` int(9) NOT NULL AUTO_INCREMENT,
        UNIQUE KEY id (id)
    );";

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
}

register_activation_hook(__FILE__,'test_install_plugin');

?>

I have no other plugins installed. Why isn't $wpdb defined? Is there a standard way to create a new database table when activating a plugin?

share|improve this question

2 Answers 2

up vote 2 down vote accepted

$wpdb is outside the scope of your plugin file, you need global $wpdb; before using $wpdb->prefix

share|improve this answer

Your plugin is trying to access $wpdb before it exists. You need to wrap it in an action hook, like so:

<?php

/**
 * Plugin Name: Test Plugin
 * Plugin URI: http://everybytcaptive.com
 * Description: A test plugin.
 * Version: 1.0
 * Author: Christopher Green
 * Author URI: http://everybytecaptive.com
 */

add_action( 'init', 'test_install_plugin' );

function test_install_plugin() {
    global $wpdb;
    global $test_db_name;

    $test_db_name = $wpdb->prefix . 'test_db_name';

    $sql = "CREATE TABLE " . $test_db_name . " (
        `id` int(9) NOT NULL AUTO_INCREMENT,
        UNIQUE KEY id (id)
    );";

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
}

// commented out for now, worry about running activation later
// register_activation_hook(__FILE__,'test_install_plugin');

I highly recommend devouring everything you can find with Google relating to actions and filters in WordPress. They are core concepts that you need to fully understand in order to create plugins and themes effectively.

share|improve this answer
    
well technically, in the context of the code that was posted, it doesn't have to be moved into an action, $wpdb is defined when the plugin file loads, it just needs to be globalized first. –  Milo Feb 4 '13 at 19:55
    
@Milo: Ahhh, thanks for the clarification, I thought that if accessed outside of a function in a plugin, it had global scope already. I also didn't know that $wpdb was instantiated prior to the plugin being loaded. Learn something new every Question! –  akTed Feb 4 '13 at 22:02
    
@AKTed Indeed, $wpdb does have global scope when accessed outside of a function, but not during a plugin's activation. –  cg433n Feb 4 '13 at 23:54
    
@cg433n: That's good to know. So if I understand correctly, in the code in your Question, your global $wpdb reference (inside of test_install_plugin()) hasn't been instantiated yet at the point in time when register_activation_hook() is fired, is that right? –  akTed Feb 5 '13 at 0:51
    
$wpdb was instantiated inside of test_install_plugin(), because I globalized it (on the first line inside of the plugin). The error occurred when PHP considered $wpdb to be undefined at the very first line of the script ($wpdb->prefix), or outside of any function, where it normally wouldn't have needed globalizing (except, as I've found, during the plugin activation routine). I don't think the error really had anything to do with $wpdb as it appeared in the function. –  cg433n Feb 5 '13 at 2:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.