Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$wpdb is null despite being global

I am working on a plugin the needs to create a database and insert data into it, I have the table creating part done, but there is an error whenever I try and use $wpdb to insert data saying that insert() could not be called on a null object.

Here is a minimal version:

<?php
/*
Plugin Name: Test
*/

function activation() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'testing';
    $charset_collate = $wpdb->get_charset_collate();

    # create table
    if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
        $sql = "CREATE TABLE " . $table_name . " (
          id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
          name TEXT NOT NULL,
          PRIMARY KEY  (id)
        ) " . $charset_collate . ";";

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

function html($atts) {
    $out = "";
    return "<form action='wp-content/plugins/test/submit.php' method='post'><input type='text' name='name'><input type='submit' name='submit'></form>";
}

# setup and cleanup hooks
register_activation_hook(__FILE__, "activation");
add_shortcode('testing', 'html');

Here is the form submit file:

<?php

function handle() {
    global $wpdb;

    if (isset($_POST['submit'])) {
        $wpdb->insert('wp_testing', array('name' => "test"));
    }
}

handle();

I read this question: $wpdb is null even after 'global $wpdb and it is pretty unclear, but seems to indicate that $wpdb must be used within a function, so I wrapped it in one. Any ideas on why this is?

like image 267
Jacob Morris Avatar asked Oct 15 '25 13:10

Jacob Morris


1 Answers

fix If you post a form directly to a PHP file without loading WordPress, none of its functions will be available unless you require wp-load.php. This is why add_action and $wpdb were undefined.

See the comments below and the original answer for details and other ways to post forms in WordPress.

original answer You don't seem to have the handle() function tied to any hook so it's loading and running as WordPress is including the necessary files, but before it actually loads up $wpdb. That's why $wpdb is not defined - it doesn't exist yet. Try this:

<?php
function handle() {
  global $wpdb;

  if( isset( $_POST[ 'submit' ] ) ){
    $wpdb->insert( 'wp_testing', array( 'name' => 'test' ) );
  }
}

//handle();
add_action( 'init', 'handle' );

I'd also consider prefixing the handle() function (or better yet, wrap it in a class) to avoid naming collisions. Something like:

<?php
function jacob_morris_handle() {
  global $wpdb;

  if( isset( $_POST[ 'submit' ] ) ){
    $wpdb->insert( 'wp_testing', array( 'name' => 'test' ) );
  }
}

//handle();
add_action( 'init', 'jacob_morris_handle' );

or

<?php
class JacobMorris {
  function handle() {
    global $wpdb;

    if( isset( $_POST[ 'submit' ] ) ){
      $wpdb->insert( 'wp_testing', array( 'name' => 'test' ) );
    }
  }

  function __construct(){
    add_action( 'init', array( $this, 'handle' ) );
  }
}
new JacobMorris();
like image 145
I'm Joe Too Avatar answered Oct 18 '25 07:10

I'm Joe Too



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!