switch_to_blog()WP 3.0.0

Switches to the specified blog in a multisite system.

Switches all global variables to the specified blog in a multisite system. Useful when you need to retrieve posts and other information from another blog.

Does not switch the following:

To switch back to the current blog, use restore_current_blog().

Noterestore_current_blog() only undoes the last switch. It needs to be called as many times as the switch was called (even if to the same blog). For example:

// now on site 1, switching to 2
switch_to_blog( 2 );
// and again
switch_to_blog( 2 );
// undo the switch
restore_current_blog();
// we are still on blog 2, need to call again
restore_current_blog();
// now we are on blog 1, where we started

If switching to a blog (network site) that we are already on, then the function executes instantly (no full switch occurs), in this case, only the hook switch_blog executes without any additional operations:

switch_to_blog( 2 );
// another switch
switch_to_blog( 2 );

IMPORTANT NOTE: a feature of the function that may redirect to the switched blog.

The function sets a redirect hook to the switched blog on the event template_redirect.

Thus, upon reaching this event (if the switch has not been reset), a redirect will occur!

When there will be no redirect:

  • If the switch occurs after the template_redirect event, for example, somewhere in the template, because the event has already occurred (passed).
  • If the switch is reset to the blog using restore_current_blog().
  • If switched back to the current blog using the same switch_to_blog().

This function only affects the data of the switched site (variables, database). It does not provide access to the code, classes, functions that are only on the switched site but not on the current one (from which the switch occurs). It also does not switch themes or activate plugins that should only work on the switched site.

1 time — 0.00094 sec (slow) | 50000 times — 5.201680 sec (fast) | PHP 7.4.8, WP 5.7.2
Hooks from the function

Returns

true. Always returns true.

Usage

switch_to_blog( $new_blog, $deprecated );
$new_blog(integer) (required)
ID of the blog to switch to.
Default: current blog
$deprecated
Not used
Default: null

Examples

0

#1 Single Switching

Let's switch to blog 5 to display its posts and go back to the current blog.

// switch to blog 5
switch_to_blog( 5 );

// Output the data of the blog we switched to
// Getting posts from blog 5
$myposts = get_posts();
foreach( $myposts as $post ){
	echo esc_html( $post->post_title ) .'<br>';
}
wp_reset_postdata();

// back to the current blog
restore_current_blog();
0

#2 Multiple Switching

Before you can switch to another blog, you must first go back to the current blog...

foreach( $blog_ids as $blog_id ){

	switch_to_blog( $blog_id );

	// process the data of the blog to which we have switched.

	restore_current_blog();
}

Note: If you do not call restore_current_blog() after every switch_to_blog(), WordPress can get into a state that can potentially build the wrong urls for the site.

0

#3 global $switched note

When using switch_to_blog() outside of WordPress, you need to have the global $switched defined. The variable for defining which blog ID to target, may also not be $blog_id, because it is used by WP Core.

The below example will NOT create a post within the correct blog_id, unless $switched is defined.

<?php
require_once '../wp-load.php';

global $switched;

$blog_id_target = 2;
switch_to_blog( $blog_id_target );

// Create a post programmatically, for blog 2.
$id = wp_insert_post(
	array(
		'post_author'   => 1,
		'post_status'   => 'publish',
		'post_type'     => 'custom_post_type',
		'post_content'  => 'Post body here',
		'post_title'    => 'Post title here'
	)
);
?>

Notes

  • See: restore_current_blog()
  • Global. wpdb. $wpdb WordPress database abstraction object.
  • Global. Int. $blog_id
  • Global. Array. $_wp_switched_stack
  • Global. true|false. $switched
  • Global. String. $table_prefix The database table prefix.
  • Global. WP_Object_Cache. $wp_object_cache

Changelog

Since 3.0.0 Introduced.

switch_to_blog() code WP 6.8.3

function switch_to_blog( $new_blog_id, $deprecated = null ) {
	global $wpdb;

	$prev_blog_id = get_current_blog_id();
	if ( empty( $new_blog_id ) ) {
		$new_blog_id = $prev_blog_id;
	}

	$GLOBALS['_wp_switched_stack'][] = $prev_blog_id;

	/*
	 * If we're switching to the same blog id that we're on,
	 * set the right vars, do the associated actions, but skip
	 * the extra unnecessary work
	 */
	if ( $new_blog_id === $prev_blog_id ) {
		/**
		 * Fires when the blog is switched.
		 *
		 * @since MU (3.0.0)
		 * @since 5.4.0 The `$context` parameter was added.
		 *
		 * @param int    $new_blog_id  New blog ID.
		 * @param int    $prev_blog_id Previous blog ID.
		 * @param string $context      Additional context. Accepts 'switch' when called from switch_to_blog()
		 *                             or 'restore' when called from restore_current_blog().
		 */
		do_action( 'switch_blog', $new_blog_id, $prev_blog_id, 'switch' );

		$GLOBALS['switched'] = true;

		return true;
	}

	$wpdb->set_blog_id( $new_blog_id );
	$GLOBALS['table_prefix'] = $wpdb->get_blog_prefix();
	$GLOBALS['blog_id']      = $new_blog_id;

	if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
		wp_cache_switch_to_blog( $new_blog_id );
	} else {
		global $wp_object_cache;

		if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) {
			$global_groups = $wp_object_cache->global_groups;
		} else {
			$global_groups = false;
		}

		wp_cache_init();

		if ( function_exists( 'wp_cache_add_global_groups' ) ) {
			if ( is_array( $global_groups ) ) {
				wp_cache_add_global_groups( $global_groups );
			} else {
				wp_cache_add_global_groups(
					array(
						'blog-details',
						'blog-id-cache',
						'blog-lookup',
						'blog_meta',
						'global-posts',
						'image_editor',
						'networks',
						'network-queries',
						'sites',
						'site-details',
						'site-options',
						'site-queries',
						'site-transient',
						'theme_files',
						'rss',
						'users',
						'user-queries',
						'user_meta',
						'useremail',
						'userlogins',
						'userslugs',
					)
				);
			}

			wp_cache_add_non_persistent_groups( array( 'counts', 'plugins', 'theme_json' ) );
		}
	}

	/** This filter is documented in wp-includes/ms-blogs.php */
	do_action( 'switch_blog', $new_blog_id, $prev_blog_id, 'switch' );

	$GLOBALS['switched'] = true;

	return true;
}