How to modify WordPress database table function without losing changes on updates

I’m running two WordPress installations that need to share the same content database. I want both sites to use identical article and metadata tables.

Right now I’ve set up custom table definitions in my second site’s configuration:

define( 'SHARED_ARTICLES_TABLE', 'mainsite_posts' );
define( 'SHARED_METADATA_TABLE', 'mainsite_postmeta' );

I also modified the database class in wp-includes/wp-db.php around line 1050:

if ( isset( $db_tables['posts'] ) && defined( 'SHARED_ARTICLES_TABLE' ) )
    $db_tables['posts'] = SHARED_ARTICLES_TABLE;
if ( isset( $db_tables['postmeta'] ) && defined( 'SHARED_METADATA_TABLE' ) )
    $db_tables['postmeta'] = SHARED_METADATA_TABLE;

This works great and both sites now display the same content. However, when WordPress updates, my core file changes get wiped out.

I tried creating a custom function in my theme’s functions.php to replace the core functionality:

add_filter( 'database_tables', 'custom_table_override', 15, 2 );
function custom_table_override( $table_scope = 'all', $use_prefix = true, $site_id = 0 ) {
    
    if ( isset( $db_tables['posts'] ) && defined( 'SHARED_ARTICLES_TABLE' ) )
        $db_tables['posts'] = SHARED_ARTICLES_TABLE;
        
    if ( isset( $db_tables['postmeta'] ) && defined( 'SHARED_METADATA_TABLE' ) )
        $db_tables['postmeta'] = SHARED_METADATA_TABLE;
        
    return $db_tables;
}

But this crashes my site with a 500 error. What’s the proper way to override WordPress core database functions so my changes survive updates?

The issue stems from attempting to use an undefined filter in your implementation, which leads to the 500 error. It’s crucial to avoid modifying core files like wp-db.php. Instead, consider creating a custom wrapper for the wpdb class within a dedicated plugin. In this way, you can safely alter the tables property during the initialization phase. Alternatively, leveraging the wp_loaded action lets you update the global $wpdb object’s table references after WordPress has loaded, but before executing any queries. This approach ensures your modifications remain intact through updates.

WordPress multisite with shared databases might work better than forcing table overrides. But if you’re stuck with your current setup, here’s the cleanest fix: use the init action to modify the global $wpdb object directly. Create a plugin file and add add_action('init', function() { global $wpdb; $wpdb->posts = SHARED_ARTICLES_TABLE; $wpdb->postmeta = SHARED_METADATA_TABLE; }); This runs early enough to catch most queries but late enough that wpdb is ready. I’ve used this on production sites and it survives updates fine. Just make sure your shared tables have identical structure and the prefixes match what you expect.

your filter function’s broken - $db_tables isn’t defined in that scope. skip functions.php and use a must-use plugin instead. create wp-content/mu-plugins/shared-tables.php and hook directly into the wpdb object after it’s initialized. way cleaner than messing with core files.