In my multisite setup I have multiple environments that I want to share the same database, but use different domains.

  • server1.example.com
  • server2.example.com
  • example.com

... each of those would point to the same database. This works perfectly fine in a standard WP install using define( 'WP_HOME', 'http://server1.example.com' ); and define( 'WP_SITEURL', 'http://server1.example.com' );.

When you add multisite to the mix it breaks.

The problem is that the wp_blogs table defines the domains too, so I need a way to define them in the config file. Is there anyway to do that?


When WordPress loads multisite, it includes the relevant MS specific files in wp-settings.php

The relevant lines:

// Initialize multisite if enabled.
if ( is_multisite() ) {
    require( ABSPATH . WPINC . '/ms-blogs.php' );
    require( ABSPATH . WPINC . '/ms-settings.php' );
} elseif ( ! defined( 'MULTISITE' ) ) {
    define( 'MULTISITE', false );

ms-settings.php serves a similar purpose as wp-settings.php: loads the multisite environment, and -- more importantly for our purposes -- sets up the current site (collection of blogs) and blog. But there's also these few gems:

if ( defined( 'SUNRISE' ) )
    include_once( WP_CONTENT_DIR . '/sunrise.php' );

/** Check for and define SUBDOMAIN_INSTALL and the deprecated VHOST constant. */

    // setup current site and blog

Most important: if(defined('SUNRISE')). This lets you drop a sunrise.php file in your wp-content directory. It gets included if you define('SUNRISE', true); in your wp-config.php. This file is the same one that's used for domain mapping to setup the current site and blog based on the custom domains. You can use it to set up your own site and blog rather than let WordPress do it for you.

Quick example -- this works okay, but probably needs some improvement.

// sunrise.php

$host = $_SERVER['HTTP_HOST'];

if('wpmscustom.dev' == $host)
    // switch the host.
    $host = 'wpms.dev';

    $sql = $wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE domain = %s LIMIT 1", $host);
    // this probably needs some work.
    $path = explode('/', ltrim($_SERVER['REQUEST_URI'], '/'));
        $path = '/' . $path[0];
        $path = '/';

    $sql = $wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE domain = %s AND path = %s LIMIT 1", $host, $path);

if($_blog = $wpdb->get_row($sql))
    $current_blog = $_blog;

    $blog_id = $_blog->blog_id;
    $site_id = $current_blog->site_id;

    // set current site
    $current_site = $wpdb->get_row(
        $wpdb->prepare("SELECT * from {$wpdb->site} WHERE id = %d", $site_id)
    $current_site->blog_id = $blog_id;

    $current_site = get_current_site_name($current_site);

Since @kaiser will likely chime in to say that $_SERVER['HTTP_HOST'] is unreliable, you may want to make sure your server actually has it available.

Or do something like this...

    $host = $_SERVER['HTTP_HOST'];
    $host = $_SERVER['SERVER_NAME'];

You can drop the above sunrise.php into your local install and put define('SUNRISE', true); into your local's wp-config.

| improve this answer | |
  • 1
    +1 and yeah, I would have ;) Btw: Why didn't you link your gist? Another thing (I don't know if this is available for a sunrise DropIn): Could be that you might need to user_trailingslashit() depending on the server settings (trailing slash or not). – kaiser Nov 26 '12 at 22:05
  • 1
    Or maybe just do WHERE path in ('/somepath', '/somepath/') to catch both? – chrisguitarguy Nov 26 '12 at 22:50
  • That sounds kool - didn't even know this was possible... – kaiser Nov 26 '12 at 23:52
  • Thanks a bunch. This has gotten me really close. Unfortunately, WP is still looking for some resources on the host I'm overriding. If you the view the source of this page trunk.createdenton.com/digital you'll see some resources from staging. and some from trunk.. I need everything to load from trunk and because they're not you're seeing the undefined function error as well. – developdaly Nov 27 '12 at 13:53
  • Well, I would start by looking at how all those resources are loaded. With an Enqueue (should be)? Or are they directly in the template? Chances are there's a filter you can use to change those URLs -- that's a separate question. – chrisguitarguy Nov 27 '12 at 13:57

Not sure if this answers your question, but I found this: http://wordpress.org/support/topic/multiple-domain-with-multisite

| improve this answer | |
  • I wish this could work, but it can't. The first issue is that the point of the domain mapping plugin is to map a site to a domain. That's not exactly what I want. Since my setup consists of local.example.com/blog1 I can't map it to staging.example.com/blog1 because it needs that subdirectory. In other words, I'm not looking for domain mapping, just subdomain replacement. – developdaly Nov 20 '12 at 15:48
  • The second issue is that the plugin requires each environment to be defined in the database itself, rather than the subdomain being defined BY the environment (i.e. in a config file). What I need to accomplish works perfectly fine in standard WP, just not with multisite. – developdaly Nov 20 '12 at 15:49

Your Answer

