0

I am trying to add a custom table handler to $wpdb.

public function __construct() {
    $this->register_tables();
}

public function register_tables() {
    global $wpdb;

    $wpdb->tables[] = 'my_new_tablename';
}

public function testing() {
    global $wpdb;
    wp_die($wpdb->my_new_tablename);
}

But when running the testing() method, I realize that $wpdb->my_new_tablename is not defined.

How may I register my own table name and make it available at $wpdb->my_new_tablename, just like as if it was a native WP table?

4
  • There is no such thing as a registered table. Custom tables aren't something that get registered, the pattern of adding a table to that array like in your code was never an official API, it was something 3rd party devs did to make it easier to retrieve the table name, nothing more, and not something that was ever supported by core.
    – Tom J Nowell
    Nov 6, 2021 at 16:07
  • @TomJNowell Thanks for your attention and great explanation. Since this is more about an opinionated way of doing things then, I guess this question has to be closed. One thing though, do you have any idea why this would not work on current versions of WP? Did anything change? Nov 6, 2021 at 16:16
  • it's extremely rare that something changing would break something if it was done correctly, but I would strongly advise against this, it provides no advantages other than the convenience of using $wpdb to get the table name, something already doable via define and constants. Most attempts to misuse WPDB this way don't involve the tables member variable at all and look like this: $wpdb->mytable = ....
    – Tom J Nowell
    Nov 6, 2021 at 17:43
  • Note that as of PHP 8.2, $wpdb->mytable = will actually generate a deprecation warning in the PHP error log. Newer versions of PHP may remove the functionality entirely unless WP chooses to implement specific opt ins (implementing this will mean dropping many older versions of PHP making it unlikely)
    – Tom J Nowell
    Nov 27, 2021 at 20:46

1 Answer 1

1

That's not what the $tables variable does, and there is no such thing as a registered custom table. These variables are an internal API not intended for plugin/theme developer use. The $wpdb->mytable pattern itself is just something someone did because they wanted to avoid prefixing manually that caught on in early WordPress articles.

The reason your code in particular doesn't work is because it's called after the set_prefix/set_blog_id methods are called by core that sets those variables. Most people get around this with $wpdb->mytable = $wpdb->prefix . 'mytable'; which is actually what set_prefix and set_blog_id do internally.

These functions are called by wp_set_wpdb_vars which is marked as private, internal, and not for plugin or theme developer use. It runs in wp-load.php which means that getting your code to work would require moving it into WordPress core itself and to a very early point in the load processs.

https://developer.wordpress.org/reference/functions/wp_set_wpdb_vars/


However, what you are trying to do is bad practice and not a good thing to do. Instead, consider one of the following options:

  • a function that returns the table name with the prefix
  • a wrapper object that has methods such as insert/update/delete that abstracts away the SQL queries to simplify your code
  • a constant or define
  • a custom post type

I would suggest option 1 as you already have an object, $this->table or $this->table_name() would be simpler, and more in line with OOP. It's even fewer characters to type.

Generally, custom post types are colloquially held up as a reliable/fast way to speed up WordPress, but unless you know how to structure your tables carefully and add the appropriate indexes this is no guarantee it will be faster, and could actually be much slower. Most speed improvements are not gained because a custom table was used, but because posts are no longer being filtered/searched by post meta via meta_query.

Unless you need to integrate with a non-WordPress database table/application or have exceptionally unique data storage requirements that require specialist data and querying ( e.g. searching geodata by radius, large directed graphs ), custom tables are rarely appropriate or the best use of developer time in a WP site.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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