函数文档

restore_current_blog()

💡 云策文档标注

概述

restore_current_blog() 函数用于在调用 switch_to_blog() 后恢复当前博客,确保全局变量状态正确。它返回布尔值表示操作成功与否,并处理数据库和缓存切换。

关键要点

  • 必须在每次 switch_to_blog() 后调用 restore_current_blog(),否则 $GLOBALS['_wp_switched_stack'] 可能非空,导致 WP 错误判断切换状态,影响如 wp_upload_dir() 的 URL 返回。
  • 函数返回 true 表示成功恢复,false 表示已在当前博客(即 $GLOBALS['_wp_switched_stack'] 为空)。
  • 内部机制包括:检查切换栈、设置数据库 ID、更新全局变量、处理缓存切换(通过 wp_cache_switch_to_blog() 或手动初始化),并触发 switch_blog 钩子。
  • 建议优先使用 restore_current_blog() 而非手动清空 $GLOBALS['_wp_switched_stack'],以避免 hack 方式。

代码示例

switch_to_blog( 5 );

/* Do stuff */

restore_current_blog();

📄 原文内容

Restores the current blog, after calling switch_to_blog() .

Description

See also

Return

bool True on success, false if we’re already on the current blog.

More Information

restore_current_blog() should be called after every switch_to_blog(). If not, a global variable which monitors the switching, $GLOBALS['_wp_switched_stack'], will not be empty even if you use switch_to_blog() to return to the original blog. If $GLOBALS['_wp_switched_stack'] is not empty, WP will think it is in a switched state and can potentially return the wrong URL for the site via wp_upload_dir(). See http://wordpress.stackexchange.com/a/123516/27757

When calling switch_to_blog() repeatedly, either call restore_current_blog() each time, or save the original blog ID until the end and call switch_to_blog() with that and do:

$GLOBALS['_wp_switched_stack'] = array();<br>
$GLOBALS['switched'] = false;

The former is probably preferable, as it is not a hack.

Source

function restore_current_blog() {
	global $wpdb;

	if ( empty( $GLOBALS['_wp_switched_stack'] ) ) {
		return false;
	}

	$new_blog_id  = array_pop( $GLOBALS['_wp_switched_stack'] );
	$prev_blog_id = get_current_blog_id();

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

		// If we still have items in the switched stack, consider ourselves still 'switched'.
		$GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );

		return true;
	}

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

	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, 'restore' );

	// If we still have items in the switched stack, consider ourselves still 'switched'.
	$GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );

	return true;
}

Hooks

do_action( ‘switch_blog’, int $new_blog_id, int $prev_blog_id, string $context )

Fires when the blog is switched.

Changelog

Version Description
MU (3.0.0) Introduced.

User Contributed Notes